@@ -10,7 +10,7 @@ ARG TARGETOS
1010ARG TARGETARCH
1111
1212WORKDIR /workspace
13- # Copy the Go Modules manifests
13+
1414COPY ../go.mod go.mod
1515COPY ../go.sum go.sum
1616# cache deps before building and copying source so that we don't need to re-download as much
@@ -20,35 +20,73 @@ RUN go mod download
2020ENV GOCACHE=/root/.cache/go-build
2121ENV GOMODCACHE=/go/pkg/mod
2222
23- # Copy the go source
2423COPY ../cmd/manager/main.go cmd/manager/main.go
2524COPY ../api/ api/
2625COPY ../internal/ internal/
2726
28- # Build
29- # the GOARCH has not a default value to allow the binary be built according to the host where the command
30- # was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
31- # the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
32- # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
27+ # Build Go binary for target platform (TARGETOS/TARGETARCH)
28+ # Docker BuildKit sets these based on --platform flag or defaults to the build host platform
3329RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \
3430 CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/manager/main.go
3531
36- # Use plugin-barman-cloud-base to get the dependencies.
37- # pip will build everything inside /usr, so we copy every file into a new
38- # destination that will then be copied into the distroless container
39- FROM ghcr.io/cloudnative-pg/plugin-barman-cloud-base:3.17.0-202601131704 AS pythonbuilder
40- # Prepare a new /usr/ directory with the files we'll need in the final image
41- RUN mkdir /new-usr/ && \
42- cp -r --parents /usr/local/lib/ /usr/lib/*-linux-gnu/ /usr/local/bin/ \
43- /new-usr/
32+ # Build Python virtualenv with all dependencies
33+ FROM debian:trixie-slim AS pythonbuilder
34+ WORKDIR /build
35+
36+ # Install postgresql-common and setup pgdg repository first
37+ RUN apt-get update && \
38+ apt-get install -y --no-install-recommends postgresql-common && \
39+ /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
40+
41+ # Install build dependencies
42+ RUN apt-get update && \
43+ apt-get install -y --no-install-recommends \
44+ python3 \
45+ python3-venv \
46+ python3-dev \
47+ build-essential \
48+ libpq-dev \
49+ liblz4-dev \
50+ libsnappy-dev
51+
52+ COPY containers/sidecar-requirements.txt .
4453
45- # Joint process
46- # Now we put everything that was build from the origin into our
47- # distroless container
48- FROM gcr.io/distroless/python3-debian12:nonroot
54+ # Create virtualenv and install dependencies
55+ RUN python3 -m venv /venv && \
56+ /venv/bin/pip install --upgrade pip setuptools wheel && \
57+ /venv/bin/pip install --no-cache-dir -r sidecar-requirements.txt
58+
59+ # Download and extract runtime library packages and their dependencies
60+ # Using apt-cache to automatically resolve dependencies, filtering out packages
61+ # already present in the distroless base image.
62+ # Distroless package list from: https://github.com/GoogleContainerTools/distroless/blob/main/base/config.bzl
63+ # and https://github.com/GoogleContainerTools/distroless/blob/main/python3/config.bzl
64+ RUN mkdir -p /dependencies /build/downloads && \
65+ cd /build/downloads && \
66+ DISTROLESS_PACKAGES="libc6 libssl3t64 libzstd1 zlib1g libgcc-s1 libstdc++6 \
67+ libbz2-1.0 libdb5.3t64 libexpat1 liblzma5 libsqlite3-0 libuuid1 \
68+ libncursesw6 libtinfo6 libcom-err2 libcrypt1 libgssapi-krb5-2 \
69+ libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libnsl2 \
70+ libreadline8t64 libtirpc3t64 libffi8 libpython3.13-minimal \
71+ libpython3.13-stdlib python3.13-minimal python3.13-venv" && \
72+ apt-cache depends --recurse --no-recommends --no-suggests \
73+ --no-conflicts --no-breaks --no-replaces --no-enhances \
74+ $DISTROLESS_PACKAGES 2>/dev/null | grep "^\w" | sort -u > /tmp/distroless.txt && \
75+ apt-cache depends --recurse --no-recommends --no-suggests \
76+ --no-conflicts --no-breaks --no-replaces --no-enhances \
77+ libpq5 liblz4-1 libsnappy1v5 2>/dev/null | grep "^\w" | sort -u | \
78+ grep -v -F -x -f /tmp/distroless.txt > /tmp/packages.txt && \
79+ apt-get download $(cat /tmp/packages.txt) && \
80+ for deb in *.deb; do \
81+ dpkg -x "$deb" /dependencies; \
82+ done
83+
84+ # Final sidecar image using distroless base for minimal size and fewer packages
85+ FROM gcr.io/distroless/python3-debian13:nonroot
4986
5087ENV SUMMARY="CloudNativePG Barman plugin" \
51- DESCRIPTION="Container image that provides the barman-cloud sidecar"
88+ DESCRIPTION="Container image that provides the barman-cloud sidecar" \
89+ PATH="/venv/bin:$PATH"
5290
5391LABEL summary="$SUMMARY" \
5492 description="$DESCRIPTION" \
@@ -60,7 +98,13 @@ LABEL summary="$SUMMARY" \
6098 version="" \
6199 release="1"
62100
63- COPY --from=pythonbuilder /new-usr/* /usr/
101+ COPY --from=pythonbuilder /venv /venv
102+ COPY --from=pythonbuilder /dependencies/usr/lib /usr/lib
64103COPY --from=gobuilder /workspace/manager /manager
104+
105+ # Compile all Python bytecode as root to avoid runtime compilation
106+ USER 0:0
107+ RUN ["/venv/bin/python3", "-c", "import sysconfig, compileall; compileall.compile_dir(sysconfig.get_path('stdlib'), quiet=1); compileall.compile_dir('/venv', quiet=1)"]
108+
65109USER 26:26
66110ENTRYPOINT ["/manager"]
0 commit comments