From 02fcac206cf7df70236bf9d455e53f6f4d795bee Mon Sep 17 00:00:00 2001 From: "ardentperf-agent[bot]" <265149240+ardentperf-agent[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 01:26:55 +0000 Subject: [PATCH 1/5] build: centralize system library staging for PostGIS Port the dynamic system-library staging helper from a0822b5 to the upstream extension tree and update the shared Bake context so PostGIS can use it. --- docker-bake.hcl | 4 ++-- postgis/Dockerfile | 34 +++++----------------------- scripts/stage_system_libs.sh | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 31 deletions(-) create mode 100755 scripts/stage_system_libs.sh diff --git a/docker-bake.hcl b/docker-bake.hcl index d99d11f5..51297ac4 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -30,8 +30,8 @@ target "default" { "linux/arm64" ] - dockerfile = "Dockerfile" - context = "${metadata.name}/" + dockerfile = "${metadata.name}/Dockerfile" + context = "." name = getBuildName(metadata.name, build.distro, build.pgVersion) tags = [ diff --git a/postgis/Dockerfile b/postgis/Dockerfile index 88823042..137d1eb6 100644 --- a/postgis/Dockerfile +++ b/postgis/Dockerfile @@ -7,6 +7,8 @@ ARG POSTGIS_MAJOR USER 0 +COPY scripts/stage_system_libs.sh /usr/local/bin/stage_system_libs.sh + RUN set -eux && \ # Initial system libraries ldconfig -p | awk '{print $NF}' | grep '^/' | sort | uniq > /tmp/base-image-libs.out && \ @@ -29,35 +31,9 @@ RUN sed -i "s/'\$libdir\//'/g" \ /usr/share/postgresql/${PG_MAJOR}/contrib/postgis*/*.sql # Gather PostGIS system libraries and their licenses -RUN mkdir -p /system /licenses && \ - # Get libraries - ldd /usr/lib/postgresql/${PG_MAJOR}/lib/address_standardizer*.so \ - /usr/lib/postgresql/${PG_MAJOR}/lib/postgis*.so \ - | awk '{print $3}' | grep '^/' | sort | uniq > /tmp/all-deps.out && \ - # Extract all the libs that aren't already part of the base image - comm -13 /tmp/base-image-libs.out /tmp/all-deps.out > /tmp/libraries.out && \ - while read -r lib; do \ - resolved=$(readlink -f "$lib"); \ - dir=$(dirname "$lib"); \ - base=$(basename "$lib"); \ - # Copy the real file - cp -a "$resolved" /system/; \ - # Reconstruct all its symlinks - for file in "$dir"/"${base%.so*}.so"*; do \ - [ -e "$file" ] || continue; \ - # If it's a symlink and it resolves to the same real file, we reconstruct it - if [ -L "$file" ] && [ "$(readlink -f "$file")" = "$resolved" ]; then \ - ln -sf "$(basename "$resolved")" "/system/$(basename "$file")"; \ - fi; \ - done; \ - done < /tmp/libraries.out && \ - # Get licenses - for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do \ - # Get the name of the pkg that installed the library - pkg=$(dpkg -S "$(basename "$lib")" | grep -v "diversion by" | awk -F: '/:/{print $1; exit}'); \ - [ -z "$pkg" ] && continue; \ - mkdir -p "/licenses/$pkg" && cp -a "/usr/share/doc/$pkg/copyright" "/licenses/$pkg/copyright"; \ - done +RUN /usr/local/bin/stage_system_libs.sh \ + /usr/lib/postgresql/${PG_MAJOR}/lib/address_standardizer*.so \ + /usr/lib/postgresql/${PG_MAJOR}/lib/postgis*.so FROM scratch diff --git a/scripts/stage_system_libs.sh b/scripts/stage_system_libs.sh new file mode 100755 index 00000000..74547dc2 --- /dev/null +++ b/scripts/stage_system_libs.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +set -eux + +# Based on the system-library staging in CloudNativePG's PostGIS image: +# https://github.com/cloudnative-pg/postgres-extensions-containers/blob/main/postgis/Dockerfile + +# Get libraries +ldd "$@" | awk '{print $3}' | grep '^/' | sort | uniq > /tmp/all-deps.out +# Extract all the libs that aren't already part of the base image +comm -13 /tmp/base-image-libs.out /tmp/all-deps.out > /tmp/libraries.out + +mkdir -p /system /licenses +while read -r lib; do + resolved=$(readlink -f "$lib") + dir=$(dirname "$lib") + base=$(basename "$lib") + # Copy the real file + cp -a "$resolved" /system/ + # Reconstruct all its symlinks + for file in "$dir"/"${base%.so*}.so"*; do + [ -e "$file" ] || continue + # If it's a symlink and it resolves to the same real file, we reconstruct it + if [ -L "$file" ] && [ "$(readlink -f "$file")" = "$resolved" ]; then + ln -sf "$(basename "$resolved")" "/system/$(basename "$file")" + fi + done +done < /tmp/libraries.out + +# Preserve aliases supplied as input, such as libmysqlclient.so. +for input_file in "$@"; do + if [ -L "$input_file" ]; then + resolved=$(readlink -f "$input_file") + ln -sf "$(basename "$resolved")" "/system/$(basename "$input_file")" + fi +done + +# Get licenses +for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do + # Get the name of the pkg that installed the library + pkg=$(dpkg -S "$(basename "$lib")" | grep -v "diversion by" | awk -F: '/:/{print $1; exit}') + [ -z "$pkg" ] && continue + mkdir -p "/licenses/$pkg" && cp -a "/usr/share/doc/$pkg/copyright" "/licenses/$pkg/copyright" +done From 9d082fecc66c1d05e3f0885398c3d3c04a231c58 Mon Sep 17 00:00:00 2001 From: "ardentperf-agent[bot]" <265149240+ardentperf-agent[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 06:03:20 +0000 Subject: [PATCH 2/5] fix: keep PostGIS staging within its build context Keep the upstream Docker Bake context unchanged by placing the helper under postgis/scripts. --- docker-bake.hcl | 4 ++-- {scripts => postgis/scripts}/stage_system_libs.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename {scripts => postgis/scripts}/stage_system_libs.sh (100%) diff --git a/docker-bake.hcl b/docker-bake.hcl index 51297ac4..d99d11f5 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -30,8 +30,8 @@ target "default" { "linux/arm64" ] - dockerfile = "${metadata.name}/Dockerfile" - context = "." + dockerfile = "Dockerfile" + context = "${metadata.name}/" name = getBuildName(metadata.name, build.distro, build.pgVersion) tags = [ diff --git a/scripts/stage_system_libs.sh b/postgis/scripts/stage_system_libs.sh similarity index 100% rename from scripts/stage_system_libs.sh rename to postgis/scripts/stage_system_libs.sh From 6f8cb716af7b3888a3ed039946ee327440142d1b Mon Sep 17 00:00:00 2001 From: "ardentperf-agent[bot]" <265149240+ardentperf-agent[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 06:06:32 +0000 Subject: [PATCH 3/5] build: use repository root for shared staging helper Restore the already-tested root-context layout so the shared helper remains in scripts/. --- docker-bake.hcl | 4 ++-- {postgis/scripts => scripts}/stage_system_libs.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename {postgis/scripts => scripts}/stage_system_libs.sh (100%) diff --git a/docker-bake.hcl b/docker-bake.hcl index d99d11f5..51297ac4 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -30,8 +30,8 @@ target "default" { "linux/arm64" ] - dockerfile = "Dockerfile" - context = "${metadata.name}/" + dockerfile = "${metadata.name}/Dockerfile" + context = "." name = getBuildName(metadata.name, build.distro, build.pgVersion) tags = [ diff --git a/postgis/scripts/stage_system_libs.sh b/scripts/stage_system_libs.sh similarity index 100% rename from postgis/scripts/stage_system_libs.sh rename to scripts/stage_system_libs.sh From a3cb4bb4eea96e7d2116cc983737de6be26c4ebb Mon Sep 17 00:00:00 2001 From: "ardentperf-agent[bot]" <265149240+ardentperf-agent[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 06:14:42 +0000 Subject: [PATCH 4/5] refactor: remove redundant alias staging PostGIS passes extension-library globs, so the helper needs only its single symlink-reconstruction pass; retain the explicit alias handling only when a future caller requires it. --- scripts/stage_system_libs.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/stage_system_libs.sh b/scripts/stage_system_libs.sh index 74547dc2..84b8ce7a 100755 --- a/scripts/stage_system_libs.sh +++ b/scripts/stage_system_libs.sh @@ -26,14 +26,6 @@ while read -r lib; do done done < /tmp/libraries.out -# Preserve aliases supplied as input, such as libmysqlclient.so. -for input_file in "$@"; do - if [ -L "$input_file" ]; then - resolved=$(readlink -f "$input_file") - ln -sf "$(basename "$resolved")" "/system/$(basename "$input_file")" - fi -done - # Get licenses for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do # Get the name of the pkg that installed the library From 3196eb37b31bc6b7a7cede6c165dea947a44b990 Mon Sep 17 00:00:00 2001 From: "ardentperf-agent[bot]" <265149240+ardentperf-agent[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 06:58:17 +0000 Subject: [PATCH 5/5] build: preserve explicit library aliases Keep the explicit input-alias pass and document why it is needed when ldd reports only a resolved soname, such as the libmysqlclient.so case. --- scripts/stage_system_libs.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/stage_system_libs.sh b/scripts/stage_system_libs.sh index 84b8ce7a..a0adbeb7 100755 --- a/scripts/stage_system_libs.sh +++ b/scripts/stage_system_libs.sh @@ -26,6 +26,15 @@ while read -r lib; do done done < /tmp/libraries.out +# Preserve aliases supplied as input, such as libmysqlclient.so. ldd may report +# only the resolved soname, so the dependency loop cannot infer this alias. +for input_file in "$@"; do + if [ -L "$input_file" ]; then + resolved=$(readlink -f "$input_file") + ln -sf "$(basename "$resolved")" "/system/$(basename "$input_file")" + fi +done + # Get licenses for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do # Get the name of the pkg that installed the library