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..a0adbeb7 --- /dev/null +++ b/scripts/stage_system_libs.sh @@ -0,0 +1,44 @@ +#!/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. 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 + 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