From a8167f0acd5727bb72cc7171d169b03974ded60e Mon Sep 17 00:00:00 2001 From: Jonathan Gonzalez V Date: Tue, 2 Sep 2025 11:23:02 +0200 Subject: [PATCH 01/13] chore: add system images into the docker-bake.hcl Signed-off-by: Jonathan Gonzalez V --- Dockerfile | 22 ++++++++++++++++++++++ docker-bake.hcl | 8 +++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a2ef41f5..959ae5c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,3 +29,25 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/* USER 26 + +FROM standard AS system +ARG BARMAN_VERSION + +# We need to break the system packages to install barman-cloud in bookworm and later +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +USER root +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + # We require build-essential and python3-dev to build lz4 on arm64 since there isn't a pre-compiled wheel available + build-essential python3-dev \ + python3-pip \ + python3-psycopg2 \ + python3-setuptools \ + && \ + pip3 install barman[cloud,azure,snappy,google,zstandard,lz4]==${BARMAN_VERSION} && \ + apt-get remove -y --purge --autoremove build-essential python3-dev && \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ + rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/* + +USER 26 diff --git a/docker-bake.hcl b/docker-bake.hcl index fdcfd024..4ed5790e 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -29,6 +29,10 @@ postgreSQLVersions = [ "17.6" ] +// Barman version to build +# renovate: datasource=github-releases depName=EnterpriseDB/barman versioning=loose +barmanVersion = "3.14.0" + extensions = [ "pgaudit", "pgvector", @@ -39,7 +43,8 @@ target "default" { matrix = { tgt = [ "minimal", - "standard" + "standard", + "system" ] pgVersion = postgreSQLVersions base = [ @@ -69,6 +74,7 @@ target "default" { PG_MAJOR = "${getMajor(pgVersion)}" BASE = "${base}" EXTENSIONS = "${getExtensionsString(pgVersion, extensions)}" + BARMAN_VERSION = "${barmanVersion}" } attest = [ "type=provenance,mode=max", From b5e58cefe08ca1904a79dfd2a3c26bb3164fcdb2 Mon Sep 17 00:00:00 2001 From: Jonathan Gonzalez V Date: Tue, 2 Sep 2025 16:27:58 +0200 Subject: [PATCH 02/13] chore: split build by major version of PostgreSQL Signed-off-by: Jonathan Gonzalez V --- .github/workflows/bake.yaml | 189 ++++---------------------- .github/workflows/bake_targets.yml | 207 +++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+), 164 deletions(-) create mode 100644 .github/workflows/bake_targets.yml diff --git a/.github/workflows/bake.yaml b/.github/workflows/bake.yaml index 9791421d..937dd71b 100644 --- a/.github/workflows/bake.yaml +++ b/.github/workflows/bake.yaml @@ -1,4 +1,4 @@ -name: Bake images +name: Bake Images on: schedule: @@ -11,181 +11,42 @@ on: - testing - production default: testing - description: "Choose the environment to bake the images for" - target: - type: string - default: "" - description: "A comma separated list of targets to build. If empty, all targets will be built." + description: "Choose the environment to bake the target for" -permissions: read-all +permissions: {} jobs: - # Start by building images for testing. We want to run security checks before pushing those to production. - testbuild: - name: Build for testing - runs-on: ubuntu-latest + get_versions: + name: Get PostgreSQL versions + runs-on: ubuntu-24.04 permissions: contents: read - packages: write - security-events: write - # Required by the cosign step - id-token: write outputs: - metadata: ${{ steps.build.outputs.metadata }} - images: ${{ steps.images.outputs.images }} + versions: ${{ steps.get_versions.outputs.versions }} steps: - name: Checkout Code uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - name: Log in to the GitHub Container registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - # TODO: review this when GitHub has linux/arm64 runners available (Q1 2025?) - # https://github.com/github/roadmap/issues/970 - - name: Set up QEMU - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 - with: - platforms: 'arm64' - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 - - - name: Build and push - uses: docker/bake-action@3acf805d94d93a86cce4ca44798a76464a75b88c # v6 - id: build - env: - environment: testing - registry: ghcr.io/${{ github.repository_owner }} - revision: ${{ github.sha }} - with: - push: true - targets: ${{ github.event.inputs.target }} - - # Get a list of the images that were built and pushed. We only care about a single tag for each image. - - name: Generated images - id: images - run: | - echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT" - - # Even if we're testing we sign the images, so we can push them to production later if that's required - - name: Install cosign - uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 - # See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/ - # and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on - # how to use cosign. - - name: Sign images + - name: Get supported PostgreSQL versions + id: get_versions run: | - echo '${{ steps.build.outputs.metadata }}' | \ - jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"' | \ - xargs cosign sign --yes - - security: - name: Security checks - runs-on: ubuntu-latest - needs: - - testbuild - strategy: - matrix: - image: ${{fromJson(needs.testbuild.outputs.images)}} - steps: - - name: Checkout Code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - - name: Log in to the GitHub Container registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + VERSIONS="$(sed -n '/postgreSQLVersions = \[/,/\]/ s/.*"\(.*\)\..*".*/\"\1\"/p' docker-bake.hcl | xargs echo | tr ' ' ',')" + echo "PostgreSQL versions: [$VERSIONS]" + echo "versions=[$VERSIONS]" >> "$GITHUB_OUTPUT" - - name: Dockle - uses: erzz/dockle-action@69369bc745ee29813f730231a821bcd4f71cd290 # v1 - with: - image: ${{ matrix.image }} - exit-code: '1' - - - name: Snyk - uses: snyk/actions/docker@master - continue-on-error: true - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - with: - image: "${{ matrix.image }}" - args: --severity-threshold=high --file=Dockerfile - - - name: Upload result to GitHub Code Scanning - uses: github/codeql-action/upload-sarif@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3 - continue-on-error: true - with: - sarif_file: snyk.sarif - - # Use the metadata generated in the `testbuild` step to find all the images - # that have been built. We copy them one by one to the production registry - # using skopeo. Then we sign the production images too. - copytoproduction: - name: Copy images to production - if: | - github.ref == 'refs/heads/main' && - ( github.event.inputs.environment == 'production' || github.event_name == 'schedule' ) - runs-on: ubuntu-latest - needs: - - testbuild - - security + Bake: + name: Bake + needs: get_versions permissions: - contents: read packages: write - security-events: write - # Required by the cosign step + contents: read id-token: write - steps: - - name: Log in to the GitHub Container registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Copy images - run: | - images=$(echo '${{ needs.testbuild.outputs.metadata }}' | - jq -r ' - .[] as $items | - ( - $items."image.name" | - split(",")[] + - "@" + - $items."containerimage.digest" - ) - ' - ) - for image in $images - do - testimageshaonly="${image%:*@*}@${image#*@}" - testimagenosha="${image%@*}" - prodimage="${testimagenosha/-testing/}" - echo "Copying ${testimageshaonly} to ${prodimage}" - docker run --quiet quay.io/skopeo/stable:v1.17.0-immutable copy -q -a \ - --dest-creds ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \ - docker://${testimageshaonly} docker://${prodimage} - done - - - name: Install cosign - uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 - - - name: Sign images - run: | - images=$(echo '${{ needs.testbuild.outputs.metadata }}' | - jq -r '.[] | - ( - ."image.name" | - sub(",.*";"") | - sub("-testing:[^@]+";"") - ) + "@" + ."containerimage.digest" - ' - ) - echo "Signing ${images}" - cosign sign --yes ${images} + security-events: write + strategy: + fail-fast: false + matrix: + version: ${{ fromJson(needs.get_versions.outputs.versions) }} + uses: ./.github/workflows/bake_targets.yml + with: + environment: ${{ github.event.inputs.environment }} + postgresql_version: ${{ matrix.version }} diff --git a/.github/workflows/bake_targets.yml b/.github/workflows/bake_targets.yml new file mode 100644 index 00000000..bbeba6a3 --- /dev/null +++ b/.github/workflows/bake_targets.yml @@ -0,0 +1,207 @@ +name: Build target images + +on: + workflow_call: + inputs: + environment: + description: "The environment to build for" + required: true + type: string + default: "testing" + postgresql_version: + description: "The PostgreSQL major version to bake" + required: true + type: string + +permissions: {} + +jobs: + testbuild: + # Start by building images for testing. We want to run security checks before pushing those to production. + name: PostgreSQL ${{ inputs.postgresql_version }} + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + # Required by the cosign step + id-token: write + outputs: + metadata: ${{ steps.build.outputs.metadata }} + images: ${{ steps.images.outputs.images }} + steps: + - name: Checkout Code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + + - name: List targets + id: targets + uses: docker/bake-action/subaction/matrix@v6 + with: + target: "default" + + - name: Filter by versions + id: extract_targets + run: | + target=$(echo '${{ steps.targets.outputs.matrix }}' | jq -r '.[] | .[] | select(match("${{ inputs.postgresql_version }}"))' | xargs echo | sed 's/ /,/g') + echo "Targets for PostgreSQL ${{ inputs.postgresql_version }}: $target" + echo "filtered_targets=$target" >> "$GITHUB_OUTPUT" + + - name: Log in to the GitHub Container registry + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # TODO: review this when GitHub has linux/arm64 runners available (Q1 2025?) + # https://github.com/github/roadmap/issues/970 + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 + with: + platforms: 'arm64' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 + + - name: Build and push + uses: docker/bake-action@3acf805d94d93a86cce4ca44798a76464a75b88c # v6 + id: build + env: + environment: testing + registry: ghcr.io/${{ github.repository_owner }} + revision: ${{ github.sha }} + with: + push: true + targets: ${{ steps.extract_targets.outputs.filtered_targets }} + + # Get a list of the images that were built and pushed. We only care about a single tag for each image. + - name: Generated images + id: images + run: | + echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT" + + # Even if we're testing we sign the images, so we can push them to production later if that's required + - name: Install cosign + uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 + # See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/ + # and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on + # how to use cosign. + - name: Sign images + run: | + echo '${{ steps.build.outputs.metadata }}' | \ + jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"' | \ + xargs cosign sign --yes + + security: + name: Security checks + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + security-events: write + needs: + - testbuild + strategy: + matrix: + image: ${{fromJson(needs.testbuild.outputs.images)}} + steps: + - name: Checkout Code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + + - name: Log in to the GitHub Container registry + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Dockle + uses: erzz/dockle-action@69369bc745ee29813f730231a821bcd4f71cd290 # v1 + with: + image: ${{ matrix.image }} + exit-code: '1' + failure-threshold: WARN + accept-keywords: key + accept-filenames: usr/share/cmake/Templates/Windows/Windows_TemporaryKey.pfx,etc/trusted-key.key,usr/share/doc/perl-IO-Socket-SSL/certs/server_enc.p12,usr/share/doc/perl-IO-Socket-SSL/certs/server.p12,usr/local/lib/python3.9/dist-packages/azure/core/settings.py,usr/local/lib/python3.8/site-packages/azure/core/settings.py,usr/share/postgresql-common/pgdg/apt.postgresql.org.asc,usr/local/lib/python3.7/dist-packages/azure/core/settings.py,etc/ssl/private/ssl-cert-snakeoil.key,usr/lib/python3.9/site-packages/azure/core/settings.py,usr/local/lib/python3.11/dist-packages/azure/core/settings.py,usr/local/lib/python3.13/dist-packages/azure/core/settings.py + + + - name: Snyk + uses: snyk/actions/docker@master + continue-on-error: true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + image: "${{ matrix.image }}" + args: --severity-threshold=high --file=Dockerfile + + - name: Upload result to GitHub Code Scanning + uses: github/codeql-action/upload-sarif@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3 + continue-on-error: true + with: + sarif_file: snyk.sarif + + # Use the metadata generated in the `testbuild` step to find all the images + # that have been built. We copy them one by one to the production registry + # using skopeo. Then we sign the production images too. + copytoproduction: + name: Copy images to production + if: | + github.ref == 'refs/heads/main' && + ( github.event.inputs.environment == 'production' || github.event_name == 'schedule' ) + runs-on: ubuntu-latest + needs: + - testbuild + - security + permissions: + contents: read + packages: write + security-events: write + # Required by the cosign step + id-token: write + steps: + - name: Log in to the GitHub Container registry + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Copy images + run: | + images=$(echo '${{ needs.testbuild.outputs.metadata }}' | + jq -r ' + .[] as $items | + ( + $items."image.name" | + split(",")[] + + "@" + + $items."containerimage.digest" + ) + ' + ) + for image in $images + do + testimageshaonly="${image%:*@*}@${image#*@}" + testimagenosha="${image%@*}" + prodimage="${testimagenosha/-testing/}" + echo "Copying ${testimageshaonly} to ${prodimage}" + docker run --quiet quay.io/skopeo/stable:v1.17.0-immutable copy -q -a \ + --dest-creds ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \ + docker://${testimageshaonly} docker://${prodimage} + done + + - name: Install cosign + uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 + + - name: Sign images + run: | + images=$(echo '${{ needs.testbuild.outputs.metadata }}' | + jq -r '.[] | + ( + ."image.name" | + sub(",.*";"") | + sub("-testing:[^@]+";"") + ) + "@" + ."containerimage.digest" + ' + ) + echo "Signing ${images}" + cosign sign --yes ${images} From 89ed950bf18f2472923e3aae1844f5fb74af9e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Thu, 4 Sep 2025 16:58:28 +0200 Subject: [PATCH 03/13] chore: cleanup dockle accept-filenames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niccolò Fei --- .github/workflows/bake_targets.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/bake_targets.yml b/.github/workflows/bake_targets.yml index bbeba6a3..1c3959b4 100644 --- a/.github/workflows/bake_targets.yml +++ b/.github/workflows/bake_targets.yml @@ -121,8 +121,7 @@ jobs: exit-code: '1' failure-threshold: WARN accept-keywords: key - accept-filenames: usr/share/cmake/Templates/Windows/Windows_TemporaryKey.pfx,etc/trusted-key.key,usr/share/doc/perl-IO-Socket-SSL/certs/server_enc.p12,usr/share/doc/perl-IO-Socket-SSL/certs/server.p12,usr/local/lib/python3.9/dist-packages/azure/core/settings.py,usr/local/lib/python3.8/site-packages/azure/core/settings.py,usr/share/postgresql-common/pgdg/apt.postgresql.org.asc,usr/local/lib/python3.7/dist-packages/azure/core/settings.py,etc/ssl/private/ssl-cert-snakeoil.key,usr/lib/python3.9/site-packages/azure/core/settings.py,usr/local/lib/python3.11/dist-packages/azure/core/settings.py,usr/local/lib/python3.13/dist-packages/azure/core/settings.py - + accept-filenames: usr/share/postgresql-common/pgdg/apt.postgresql.org.asc,etc/ssl/private/ssl-cert-snakeoil.key,usr/local/lib/python3.9/dist-packages/azure/core/settings.py,usr/local/lib/python3.11/dist-packages/azure/core/settings.py,usr/local/lib/python3.13/dist-packages/azure/core/settings.py - name: Snyk uses: snyk/actions/docker@master From bcb756ceedbd5d4f2bd86bcc055229e577350144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Thu, 4 Sep 2025 16:59:05 +0200 Subject: [PATCH 04/13] chore: fix workflow name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niccolò Fei --- .github/workflows/{bake.yaml => bake.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{bake.yaml => bake.yml} (100%) diff --git a/.github/workflows/bake.yaml b/.github/workflows/bake.yml similarity index 100% rename from .github/workflows/bake.yaml rename to .github/workflows/bake.yml From 3651b34e94c83bb2a07822d105e68efb9e2a2b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Thu, 4 Sep 2025 17:01:13 +0200 Subject: [PATCH 05/13] ci: fix indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niccolò Fei --- .github/workflows/bake_targets.yml | 122 ++++++++++++++--------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/.github/workflows/bake_targets.yml b/.github/workflows/bake_targets.yml index 1c3959b4..cdadfdff 100644 --- a/.github/workflows/bake_targets.yml +++ b/.github/workflows/bake_targets.yml @@ -29,67 +29,67 @@ jobs: metadata: ${{ steps.build.outputs.metadata }} images: ${{ steps.images.outputs.images }} steps: - - name: Checkout Code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - - name: List targets - id: targets - uses: docker/bake-action/subaction/matrix@v6 - with: - target: "default" - - - name: Filter by versions - id: extract_targets - run: | - target=$(echo '${{ steps.targets.outputs.matrix }}' | jq -r '.[] | .[] | select(match("${{ inputs.postgresql_version }}"))' | xargs echo | sed 's/ /,/g') - echo "Targets for PostgreSQL ${{ inputs.postgresql_version }}: $target" - echo "filtered_targets=$target" >> "$GITHUB_OUTPUT" - - - name: Log in to the GitHub Container registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - # TODO: review this when GitHub has linux/arm64 runners available (Q1 2025?) - # https://github.com/github/roadmap/issues/970 - - name: Set up QEMU - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 - with: - platforms: 'arm64' - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 - - - name: Build and push - uses: docker/bake-action@3acf805d94d93a86cce4ca44798a76464a75b88c # v6 - id: build - env: - environment: testing - registry: ghcr.io/${{ github.repository_owner }} - revision: ${{ github.sha }} - with: - push: true - targets: ${{ steps.extract_targets.outputs.filtered_targets }} - - # Get a list of the images that were built and pushed. We only care about a single tag for each image. - - name: Generated images - id: images - run: | - echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT" - - # Even if we're testing we sign the images, so we can push them to production later if that's required - - name: Install cosign - uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 - # See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/ - # and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on - # how to use cosign. - - name: Sign images - run: | - echo '${{ steps.build.outputs.metadata }}' | \ - jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"' | \ - xargs cosign sign --yes + - name: Checkout Code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + + - name: List targets + id: targets + uses: docker/bake-action/subaction/matrix@v6 + with: + target: "default" + + - name: Filter by versions + id: extract_targets + run: | + target=$(echo '${{ steps.targets.outputs.matrix }}' | jq -r '.[] | .[] | select(match("${{ inputs.postgresql_version }}"))' | xargs echo | sed 's/ /,/g') + echo "Targets for PostgreSQL ${{ inputs.postgresql_version }}: $target" + echo "filtered_targets=$target" >> "$GITHUB_OUTPUT" + + - name: Log in to the GitHub Container registry + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # TODO: review this when GitHub has linux/arm64 runners available (Q1 2025?) + # https://github.com/github/roadmap/issues/970 + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 + with: + platforms: 'arm64' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 + + - name: Build and push + uses: docker/bake-action@3acf805d94d93a86cce4ca44798a76464a75b88c # v6 + id: build + env: + environment: testing + registry: ghcr.io/${{ github.repository_owner }} + revision: ${{ github.sha }} + with: + push: true + targets: ${{ steps.extract_targets.outputs.filtered_targets }} + + # Get a list of the images that were built and pushed. We only care about a single tag for each image. + - name: Generated images + id: images + run: | + echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT" + + # Even if we're testing we sign the images, so we can push them to production later if that's required + - name: Install cosign + uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 + # See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/ + # and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on + # how to use cosign. + - name: Sign images + run: | + echo '${{ steps.build.outputs.metadata }}' | \ + jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"' | \ + xargs cosign sign --yes security: name: Security checks From 2c0f7a69a5a8eb5df8a5de4c57f6cf999952975b Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 5 Sep 2025 12:00:28 +0200 Subject: [PATCH 06/13] docs: documented the change Signed-off-by: Gabriele Bartolini --- README.md | 57 ++++++++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 92a278fd..3415f185 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ [![CloudNativePG](./logo/cloudnativepg.png)](https://cloudnative-pg.io/) -> **IMPORTANT:** As of January 2025, we have transitioned to a new image build -> process (see issue [#132](https://github.com/cloudnative-pg/postgres-containers/issues/132) -> for details). Previously, the images were based on the -> [Official Postgres image](https://hub.docker.com/_/postgres), maintained by the -> [PostgreSQL Docker Community](https://github.com/docker-library/postgres), -> and included Barman Cloud built from source. -> This legacy approach, referred to as `system` images, will remain available -> for backward compatibility but is planned for a future deprecation. +> **IMPORTANT:** Starting in August 2025, the [Official Postgres Image](https://hub.docker.com/_/postgres), +> maintained by the [PostgreSQL Docker Community](https://github.com/docker-library/postgres), +> has discontinued support for Debian `bullseye`. +> In response, the CloudNativePG project has completed the transition to the +> new `bake`-based build process for all `system` images. We now build directly +> on top of the official Debian slim images, fully detaching from the official +> Postgres image. Additional changes are planned as part of epic #287. --- @@ -37,17 +36,17 @@ The CNPG PostgreSQL Container Images: ## Image Types -We currently build and support two primary types of PostgreSQL images: +We currently provide and maintain three main types of PostgreSQL images: -- [`minimal`](#minimal-images) -- [`standard`](#standard-images) +* [`minimal`](#minimal-images) +* [`standard`](#standard-images) +* [`system`](#system-images) (*deprecated*) -Both `minimal` and `standard` images are intended to be used with backup -plugins, such as [Barman Cloud](https://github.com/cloudnative-pg/plugin-barman-cloud). +Both `minimal` and `standard` images are designed to work with backup plugins +such as [Barman Cloud](https://github.com/cloudnative-pg/plugin-barman-cloud). -> **Note:** for backward compatibility, we also maintain the -> [`system`](#system-images) image type. Switching from `system` images to -> `minimal` or `standard` images on an existing cluster is not supported. +The `system` images, built on top of the `standard` ones, also include the +Barman Cloud binaries. ### Minimal Images @@ -77,26 +76,16 @@ Standard images are identifiable by the `standard` tag in their names, such as: > you must use the [Barman Cloud Plugin](https://github.com/cloudnative-pg/plugin-barman-cloud) > as a replacement for the native Barman Cloud support in `system` images. -### System Images +### System Images (deprecated) -System images are based on the [Official Postgres image](https://hub.docker.com/_/postgres), -maintained by the -[PostgreSQL Docker Community](https://github.com/docker-library/postgres). -These images include additional software to extend PostgreSQL functionality: +Starting from September 2025, system images are based on the `stadard` image +and include Barman Cloud binaries. -- Barman Cloud -- PGAudit -- Postgres Failover Slots -- pgvector - -The [`Debian`](Debian) folder contains image catalogs, which can be used as: -- [`ClusterImageCatalog`](https://cloudnative-pg.io/documentation/current/image_catalog/) -- [`ImageCatalog`](https://cloudnative-pg.io/documentation/current/image_catalog/) - -> **Deprecation Notice:** System images and the associated Debian-based image -> catalogs will be deprecated in future releases of CloudNativePG and -> eventually removed. Users are encouraged to migrate to `minimal` or -> `standard` images for new clusters as soon as feasible. +> **IMPORTANT:** The `system` images are deprecated and will be removed once +> in-core support for Barman Cloud in CloudNativePG is phased out. While you +> can still use them as long as in-core Barman Cloud remains available, you +> should plan to migrate to either a `minimal` or `standard` image together +> with the Barman Cloud plugin—or adopt another supported backup solution. ## Build Attestations From e68924521fa486a0b9661eb6510c874c1cafb1b1 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 5 Sep 2025 18:34:25 +0200 Subject: [PATCH 07/13] Update README.md Co-authored-by: Jonathan Gonzalez V. Signed-off-by: Gabriele Bartolini --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3415f185..c2c8775d 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Standard images are identifiable by the `standard` tag in their names, such as: ### System Images (deprecated) -Starting from September 2025, system images are based on the `stadard` image +Starting from September 2025, system images are based on the `standard` image and include Barman Cloud binaries. > **IMPORTANT:** The `system` images are deprecated and will be removed once From e6968a55685f53efa38195fcb677c6175e60070c Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 5 Sep 2025 12:46:38 +0200 Subject: [PATCH 08/13] chore: update to `trixie` in examples Signed-off-by: Gabriele Bartolini --- BUILD.md | 6 +++--- README.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BUILD.md b/BUILD.md index 722c82a0..d83e6e04 100644 --- a/BUILD.md +++ b/BUILD.md @@ -73,10 +73,10 @@ docker buildx bake --push If you want to limit the build to a specific combination, you can specify the target in the `VERSION-TYPE-BASE` format. For example, to build an image for -PostgreSQL 17 with the `minimal` format on the `bookworm` base image: +PostgreSQL 17 with the `minimal` format on the `trixie` base image: ```bash -docker buildx bake --push postgresql-17-minimal-bookworm +docker buildx bake --push postgresql-17-minimal-trixie ``` You can also limit the build to a single platform, for example AMD64, with: @@ -90,7 +90,7 @@ The two can be mixed as well: ```bash docker buildx bake --push \ --set "*.platform=linux/amd64" \ - postgresql-17-minimal-bookworm + postgresql-17-minimal-trixie ``` ## The Distribution Registry diff --git a/README.md b/README.md index c2c8775d..114e27b3 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ They use the [APT PostgreSQL packages](https://wiki.postgresql.org/wiki/Apt) maintained by the PostgreSQL Global Development Group (PGDG). These images are identified by the inclusion of `minimal` in their tag names, -for example: `17.2-minimal-bookworm`. +for example: `17.2-minimal-trixie`. ### Standard Images @@ -69,7 +69,7 @@ following additional features: - All Locales Standard images are identifiable by the `standard` tag in their names, such as: -`17.2-standard-bookworm`. +`17.2-standard-trixie`. > **Note:** Standard images are designed to offer functionality equivalent to > the legacy `system` images when used with CloudNativePG. To achieve parity, From a277b68c43cccd1aa46dd512ce8b5167db8f1fd3 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 5 Sep 2025 18:37:21 +0200 Subject: [PATCH 09/13] chore: add comment Signed-off-by: Gabriele Bartolini --- .github/workflows/bake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/bake.yml b/.github/workflows/bake.yml index 937dd71b..8109eea6 100644 --- a/.github/workflows/bake.yml +++ b/.github/workflows/bake.yml @@ -2,6 +2,7 @@ name: Bake Images on: schedule: + # Build images once a week, on Mondays - cron: 0 8 * * 1 workflow_dispatch: inputs: From 60a7dc4af477b6ce9fa5f42e6b2e8100c01fdfac Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Sun, 7 Sep 2025 08:30:55 +0200 Subject: [PATCH 10/13] docs: Debian release matrix Closes #286 Signed-off-by: Gabriele Bartolini --- README.md | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 114e27b3..65777d94 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,38 @@ within Kubernetes environments. ## Key Features -The CNPG PostgreSQL Container Images: +CloudNativePG PostgreSQL container images: -- Are based on Debian Linux `stable` and `oldstable` -- Support **multi-architecture builds**, including `linux/amd64` and +- Are built on top of **Debian Linux** (`stable` and `oldstable`). +- Provide **multi-architecture support**, including `linux/amd64` and `linux/arm64`. -- Include **build attestations**, such as Software Bills of Materials (SBOMs) +- Ship with **build attestations**, such as Software Bills of Materials (SBOMs) and provenance metadata. -- Are published on the - [CloudNativePG GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). -- Are **automatically rebuilt weekly** (every Monday) to ensure they remain - up-to-date. +- Are published in the [CloudNativePG GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). +- Are **automatically rebuilt every week** (on Mondays) to remain up to date + with the latest upstream security and bug fixes. + +## Debian Releases + +CloudNativePG PostgreSQL container images are based on the official `stable` +and `oldstable` Debian releases, maintained and supported by the +[Debian Project](https://www.debian.org/releases/). + +The table below summarises the support lifecycle of relevant Debian versions, +including End-of-Life (EOL) and Long-Term Support (LTS) dates. + +| Name | Version | Release Date | EOL | LTS | +| ----------------------- | :-----: | :----------: | :--------: | :--------: | +| Trixie (`stable`) | 13 | 2025-08-09 | 2028-08-09 | 2030-06-30 | +| Bookworm (`oldstable`) | 12 | 2023-06-10 | 2026-06-10 | 2028-06-30 | +| Bullseye (*deprecated*) | 11 | 2021-08-14 | 2024-08-14 | 2026-08-31 | + +> **IMPORTANT:** The CloudNativePG project provides full support for +> Debian-based images until each release reaches its official End-of-Life +> (EOL). After EOL and until the start of Long-Term Support (LTS), images for +> deprecated releases are maintained on a **best-effort basis**. If +> discontinuation becomes necessary before the LTS date, a minimum +> **three-month advance notice** will be posted on this page. ## Image Types @@ -56,7 +77,7 @@ They use the [APT PostgreSQL packages](https://wiki.postgresql.org/wiki/Apt) maintained by the PostgreSQL Global Development Group (PGDG). These images are identified by the inclusion of `minimal` in their tag names, -for example: `17.2-minimal-trixie`. +for example: `17.6-minimal-trixie`. ### Standard Images @@ -69,7 +90,7 @@ following additional features: - All Locales Standard images are identifiable by the `standard` tag in their names, such as: -`17.2-standard-trixie`. +`17.6-standard-trixie`. > **Note:** Standard images are designed to offer functionality equivalent to > the legacy `system` images when used with CloudNativePG. To achieve parity, From 84335881310e1ca7f0f8f712ee93544027672437 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Sun, 7 Sep 2025 08:40:47 +0200 Subject: [PATCH 11/13] docs: use `oldoldstable` Signed-off-by: Gabriele Bartolini --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 65777d94..b0a9e951 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,18 @@ and `oldstable` Debian releases, maintained and supported by the The table below summarises the support lifecycle of relevant Debian versions, including End-of-Life (EOL) and Long-Term Support (LTS) dates. -| Name | Version | Release Date | EOL | LTS | -| ----------------------- | :-----: | :----------: | :--------: | :--------: | -| Trixie (`stable`) | 13 | 2025-08-09 | 2028-08-09 | 2030-06-30 | -| Bookworm (`oldstable`) | 12 | 2023-06-10 | 2026-06-10 | 2028-06-30 | -| Bullseye (*deprecated*) | 11 | 2021-08-14 | 2024-08-14 | 2026-08-31 | +| Name | Version | Release Date | EOL | LTS | +| ------------------------- | :-----: | :----------: | :--------: | :--------: | +| Trixie (`stable`) | 13 | 2025-08-09 | 2028-08-09 | 2030-06-30 | +| Bookworm (`oldstable`) | 12 | 2023-06-10 | 2026-06-10 | 2028-06-30 | +| Bullseye (`oldoldstable`) | 11 | 2021-08-14 | 2024-08-14 | 2026-08-31 | > **IMPORTANT:** The CloudNativePG project provides full support for > Debian-based images until each release reaches its official End-of-Life -> (EOL). After EOL and until the start of Long-Term Support (LTS), images for -> deprecated releases are maintained on a **best-effort basis**. If -> discontinuation becomes necessary before the LTS date, a minimum -> **three-month advance notice** will be posted on this page. +> (EOL). After EOL and until the start of Long-Term Support (LTS), images for the +> deprecated releases, such as `oldoldstable`, are maintained on a +> **best-effort basis**. If discontinuation becomes necessary before the LTS +> date, a minimum **three-month advance notice** will be posted on this page. ## Image Types From 1a90b5661c7611ca5e78ed6b18e9bdd305469044 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Sun, 7 Sep 2025 08:42:22 +0200 Subject: [PATCH 12/13] docs: add support Signed-off-by: Gabriele Bartolini --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b0a9e951..653da7ae 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ and `oldstable` Debian releases, maintained and supported by the The table below summarises the support lifecycle of relevant Debian versions, including End-of-Life (EOL) and Long-Term Support (LTS) dates. -| Name | Version | Release Date | EOL | LTS | -| ------------------------- | :-----: | :----------: | :--------: | :--------: | -| Trixie (`stable`) | 13 | 2025-08-09 | 2028-08-09 | 2030-06-30 | -| Bookworm (`oldstable`) | 12 | 2023-06-10 | 2026-06-10 | 2028-06-30 | -| Bullseye (`oldoldstable`) | 11 | 2021-08-14 | 2024-08-14 | 2026-08-31 | +| Name | Version | Release Date | EOL | LTS | Status | +| ------------------------- | :-----: | :----------: | :--------: | :--------: | :--------- | +| Trixie (`stable`) | 13 | 2025-08-09 | 2028-08-09 | 2030-06-30 | Supported | +| Bookworm (`oldstable`) | 12 | 2023-06-10 | 2026-06-10 | 2028-06-30 | Supported | +| Bullseye (`oldoldstable`) | 11 | 2021-08-14 | 2024-08-14 | 2026-08-31 | Deprecated | > **IMPORTANT:** The CloudNativePG project provides full support for > Debian-based images until each release reaches its official End-of-Life From c759ffd202c43d16888eab980b784b855a3ff274 Mon Sep 17 00:00:00 2001 From: Marco Nenciarini Date: Mon, 8 Sep 2025 11:40:10 +0200 Subject: [PATCH 13/13] chore: disable pip cache (~37 MB less) Signed-off-by: Marco Nenciarini --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 959ae5c3..2a9c90a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,7 +45,7 @@ RUN apt-get update && \ python3-psycopg2 \ python3-setuptools \ && \ - pip3 install barman[cloud,azure,snappy,google,zstandard,lz4]==${BARMAN_VERSION} && \ + pip3 install --no-cache-dir barman[cloud,azure,snappy,google,zstandard,lz4]==${BARMAN_VERSION} && \ apt-get remove -y --purge --autoremove build-essential python3-dev && \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/*