From e62a48297809773d53a5161271e7ad2ef9062026 Mon Sep 17 00:00:00 2001 From: Francesco Canovai Date: Fri, 3 Jan 2025 18:28:27 +0100 Subject: [PATCH 01/13] ci: build minimal and standard images Build images without barman-cloud, to be used with backup plugins. Closes #132 Signed-off-by: Francesco Canovai --- .github/workflows/bake.yaml | 146 ++++++++++++++++++++++++++++++++++++ Dockerfile | 37 +++++++++ README.md | 77 ++++++++++++++++--- docker-bake.hcl | 107 ++++++++++++++++++++++++++ 4 files changed, 356 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/bake.yaml create mode 100644 Dockerfile create mode 100644 docker-bake.hcl diff --git a/.github/workflows/bake.yaml b/.github/workflows/bake.yaml new file mode 100644 index 00000000..f35cf93c --- /dev/null +++ b/.github/workflows/bake.yaml @@ -0,0 +1,146 @@ +name: Bake images + +on: + schedule: + - cron: 0 8 * * 1 + workflow_dispatch: + inputs: + environment: + type: choice + options: + - testing + - production + default: testing + description: "Choose the environment to bake the images for" + +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 + permissions: + contents: read + packages: write + security-events: write + outputs: + metadata: ${{ steps.build.outputs.metadata }} + images: ${{ steps.images.outputs.images }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Log in to the GitHub Container registry + uses: docker/login-action@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@v3 + with: + platforms: 'arm64' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/bake-action@v6 + id: build + env: + environment: testing + registry: ghcr.io/${{ github.repository_owner }} + revision: ${{ github.sha }} + with: + push: true + + # 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" + + 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@v4 + + - name: Log in to the GitHub Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Dockle + uses: erzz/dockle-action@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@v3 + continue-on-error: true + with: + sarif_file: snyk.sarif + + # Build the image for production. + # + # TODO: no need to rebuild everything, just copy the testing images we have generated to the production registry + # if we get here and we are building for production. + prodbuild: + if: github.event.inputs.environment == 'production' || github.event_name == 'schedule' + name: Build for production + runs-on: ubuntu-latest + needs: + - security + permissions: + contents: read + packages: write + security-events: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Log in to the GitHub Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: 'arm64' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/bake-action@v6 + id: build + env: + environment: production + registry: ghcr.io/${{ github.repository_owner }} + revision: ${{ github.sha }} + with: + push: true diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..548e5319 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +ARG BASE=debian:bookworm-slim +FROM $BASE AS minimal + +ARG PG_VERSION +ARG PG_MAJOR=${PG_VERSION%%.*} + +ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin + +RUN apt-get update && \ + apt-get install -y --no-install-recommends postgresql-common ca-certificates gnupg && \ + /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \ + apt-get install --no-install-recommends -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" postgresql-common -y && \ + sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf && \ + apt-get install --no-install-recommends \ + -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" "postgresql-${PG_MAJOR}=${PG_VERSION}*" -y && \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ + rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/* + +RUN usermod -u 26 postgres +USER 26 + + +FROM minimal AS standard + +LABEL org.opencontainers.image.title="CloudNativePG PostgreSQL $PG_VERSION standard" +LABEL org.opencontainers.image.description="A standard PostgreSQL $PG_VERSION container image, with a minimal set of extensions and all the locales" + +USER root +RUN apt-get update && \ + apt-get install -y --no-install-recommends locales-all \ + "postgresql-${PG_MAJOR}-pgaudit" \ + "postgresql-${PG_MAJOR}-pgvector" \ + "postgresql-${PG_MAJOR}-pg-failover-slots" && \ + 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/README.md b/README.md index f23835e4..1ea37c9e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,26 @@ for all available PostgreSQL versions (13 to 17) to be used as operands with the [CloudNativePG operator](https://cloudnative-pg.io) for Kubernetes. +## Images + +We build three types of images: +* [system](#system) +* [minimal](#minimal) +* [standard](#standard) + +Switching from system images to minimal or standard images on an existing +cluster is not currently supported. + +Minimal and standard images are supposed to be used alongside a backup plugin +like [Barman Cloud](https://github.com/cloudnative-pg/plugin-barman-cloud). + +Images are available via +[GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). + +Currently, images are automatically rebuilt once a week (Monday). + +### System + These images are built on top of the [Official Postgres image](https://hub.docker.com/_/postgres) maintained by the [PostgreSQL Docker Community](https://github.com/docker-library/postgres), by adding the following software: @@ -14,7 +34,52 @@ by adding the following software: - Postgres Failover Slots - pgvector -Currently, images are automatically rebuilt once a week (Monday). +### Minimal + +These images are build on top of [official Debian images](https://hub.docker.com/_/debian) +by installing PostgreSQL. + +Minimal images include `minimal` in the tag name, e.g. +`17.2-standard-bookworm`. + +### Standard + +These images are build on top of the minimal images by adding the following +software: + +- PGAudit +- Postgres Failover Slots +- pgvector + +and all the locales. + +Standard images include `standard` in the tag name, e.g. +`17.2-standard-bookworm`. + +## SBOMs + +Software Bills of Materials (SBOMs) are available for minimal and standard +images. The SBOM for an image can be retrieved with the following command: + +```shell +docker buildx imagetools inspect --format "{{ json .SBOM.SPDX}}" +``` + +## Testing image builds + +Minimal and standard image builds can be tested running bake manually. +You will need a container registry and a builder with the `docker-container` +driver. + +``` +registry= docker buildx bake --builder --push +``` + +## License and copyright + +This software is available under [Apache License 2.0](LICENSE). + +Copyright The CloudNativePG Contributors. Barman Cloud is distributed by EnterpriseDB under the [GNU GPL 3 License](https://github.com/EnterpriseDB/barman/blob/master/LICENSE). @@ -28,18 +93,8 @@ Postgres Failover Slots is distributed by EnterpriseDB under the pgvector is distributed under the [PostgreSQL License](https://github.com/pgvector/pgvector/blob/master/LICENSE). -Images are available via -[GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). - -## License and copyright - -This software is available under [Apache License 2.0](LICENSE). - -Copyright The CloudNativePG Contributors. - ## Trademarks *[Postgres, PostgreSQL and the Slonik Logo](https://www.postgresql.org/about/policies/trademarks/) are trademarks or registered trademarks of the PostgreSQL Community Association of Canada, and used with their permission.* - diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 00000000..d54d7cf0 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,107 @@ +variable "environment" { + default = "testing" + validation { + condition = contains(["testing", "production"], environment) + error_message = "environment must be either testing or production" + } +} + +variable "registry" { + default = "localhost:5000" +} + +// Use the revision variable to identify the commit that generated the image +variable "revision" { + default = "" +} + +fullname = ( environment == "testing") ? "${registry}/postgresql-testing" : "{registry}/postgresql" +now = timestamp() + +target "default" { + matrix = { + tgt = [ + "minimal", + "standard" + ] + pgVersion = [ + "13.18", + "14.15", + "15.10", + "16.6", + "17.2" + ] + base = [ + // renovate: datasource=docker versioning=loose + "debian:bookworm-slim@sha256:d365f4920711a9074c4bcd178e8f457ee59250426441ab2a5f8106ed8fe948eb", + // renovate: datasource=docker versioning=loose + "debian:bullseye-slim@sha256:b0c91cc181796d34c53f7ea106fbcddaf87f3e601cc371af6a24a019a489c980" + ] + } + platforms = [ + "linux/amd64", + "linux/arm64" + ] + dockerfile = "Dockerfile" + name = "postgresql-${index(split(".",pgVersion),0)}-${tgt}-${distroVersion(base)}" + tags = [ + "${fullname}:${index(split(".",pgVersion),0)}-${tgt}-${distroVersion(base)}", + "${fullname}:${pgVersion}-${tgt}-${distroVersion(base)}", + "${fullname}:${pgVersion}-${formatdate("YYYYMMDDhhmm", now)}-${tgt}-${distroVersion(base)}" + ] + context = "." + target = "${tgt}" + args = { + PG_VERSION = "${pgVersion}" + BASE = "${base}" + } + attest = [ + "type=provenance,mode=max", + "type=sbom" + ] + annotations = [ + "index,manifest:org.opencontainers.image.created=${now}", + "index,manifest:org.opencontainers.image.url=https://github.com/cloudnative-pg/postgres-containers", + "index,manifest:org.opencontainers.image.source=https://github.com/cloudnative-pg/postgres-containers", + "index,manifest:org.opencontainers.image.version=${pgVersion}", + "index,manifest:org.opencontainers.image.revision=${revision}", + "index,manifest:org.opencontainers.image.vendor=The CloudNativePG Contributors", + "index,manifest:org.opencontainers.image.title=CloudNativePG PostgreSQL ${pgVersion} ${tgt}", + "index,manifest:org.opencontainers.image.description=A ${tgt} PostgreSQL ${pgVersion} container image", + "index,manifest:org.opencontainers.image.documentation=https://github.com/cloudnative-pg/postgres-containers", + "index,manifest:org.opencontainers.image.authors=The CloudNativePG Contributors", + "index,manifest:org.opencontainers.image.licenses=Apache-2.0", + "index,manifest:org.opencontainers.image.base.name=docker.io/library/${tag(base)}", + "index,manifest:org.opencontainers.image.base.digest=${digest(base)}" + ] + labels = { + "org.opencontainers.image.created" = "${now}", + "org.opencontainers.image.url" = "https://github.com/cloudnative-pg/postgres-containers", + "org.opencontainers.image.source" = "https://github.com/cloudnative-pg/postgres-containers", + "org.opencontainers.image.version" = "${pgVersion}", + "org.opencontainers.image.revision" = "${revision}", + "org.opencontainers.image.vendor" = "The CloudNativePG Contributors", + "org.opencontainers.image.title" = "CloudNativePG PostgreSQL ${pgVersion} ${tgt}", + "org.opencontainers.image.description" = "A ${tgt} PostgreSQL ${pgVersion} container image", + "org.opencontainers.image.documentation" = "https://github.com/cloudnative-pg/postgres-containers", + "org.opencontainers.image.authors" = "The CloudNativePG Contributors", + "org.opencontainers.image.licenses" = "Apache-2.0" + "org.opencontainers.image.base.name" = "docker.io/library/debian:${tag(base)}" + "org.opencontainers.image.base.digest" = "${digest(base)}" + } +} + +function tag { + params = [ imageNameWithSha ] + result = index(split("@", index(split(":", imageNameWithSha), 1)), 0) +} + +function distroVersion { + params = [ imageNameWithSha ] + result = index(split("-", tag(imageNameWithSha)), 0) +} + +function digest { + params = [ imageNameWithSha ] + result = index(split("@", imageNameWithSha), 1) +} From 4e18e34392fa32d7a5b5abba0994c63e2ba7b57c Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Thu, 9 Jan 2025 17:32:34 +0100 Subject: [PATCH 02/13] docs: add BUILD.md file Signed-off-by: Gabriele Bartolini --- BUILD.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ docker-bake.hcl | 20 +++++++----- 2 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 BUILD.md diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 00000000..1bd1228f --- /dev/null +++ b/BUILD.md @@ -0,0 +1,87 @@ +# Building PostgreSQL Container Images for CloudNativePG + +This guide outlines the process for building PostgreSQL operand images for +CloudNativePG using [Docker Bake](https://docs.docker.com/build/bake/) and a +[GitHub workflow](.github/workflows/bake.yaml). + +The central component of this framework is the +[Bake file (`docker-bake.hcl`)](docker-bake.hcl). + +## Prerequisites + +Ensure the following tools and components are available before proceeding: + +1. [Docker Buildx](https://github.com/docker/buildx): A CLI plugin for advanced +image building. +2. Build Driver for Multi-Architecture Images: For example, `docker-container` +(see [Build Drivers](https://docs.docker.com/build/builders/drivers/)). +3. [Distribution Registry](https://distribution.github.io/distribution/): +Formerly known as Docker Registry, to host and manage the built images. + +## Verifying Requirements + +To confirm your environment is properly set up, run: + +```bash +docker buildx bake --check +``` + +If warnings appear, you may need to switch to a different build driver (e.g., +`docker-container`). Use the following commands to configure it: + +```bash +docker buildx create --driver docker-container --name docker-container +docker buildx use docker-container +``` + +## Default Target + +The `default` target in Bake represents a Cartesian product of the following +dimensions: + +- **Base Image** +- **Format** (e.g. `minimal` or `standard`) +- **Platforms** +- **PostgreSQL Versions** + +## Building Images + +To build PostgreSQL images using the `default` target — that is, for all the +combinations of base image, format, platforms, and PostgreSQL versions — run: + +```bash +docker buildx bake --push +``` + +> *Note:* The `--push` flag is required to upload the images to the registry. +> Without it, the images will remain cached within the builder container, +> making testing impossible. + +If you want to limit the build to a specific combination, you can specify the +target in the `VERSION-FORMAT-BASE` format. For example, to build an image for +PostgreSQL 17 with the `minimal` format on the `bullseye` base image: + +```bash +docker buildx bake --push postgresql-17-minimal-bullseye +``` + +You can also limit the build to a single platform, for example AMD64, with: + +```bash +docker buildx bake --set *.platform=linux/amd6 +``` + +## SBOMs + +Software Bills of Materials (SBOMs) are available for minimal and standard +images. The SBOM for an image can be retrieved with the following command: + +```shell +docker buildx imagetools inspect --format "{{ json .SBOM.SPDX}}" +``` + +## Trademarks + +*[Postgres, PostgreSQL and the Slonik Logo](https://www.postgresql.org/about/policies/trademarks/) +are trademarks or registered trademarks of the PostgreSQL Community Association +of Canada, and used with their permission.* diff --git a/docker-bake.hcl b/docker-bake.hcl index d54d7cf0..f458ab5f 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -17,6 +17,8 @@ variable "revision" { fullname = ( environment == "testing") ? "${registry}/postgresql-testing" : "{registry}/postgresql" now = timestamp() +authors = "The CloudNativePG Contributors" +url = "https://github.com/cloudnative-pg/postgres-containers" target "default" { matrix = { @@ -61,30 +63,30 @@ target "default" { ] annotations = [ "index,manifest:org.opencontainers.image.created=${now}", - "index,manifest:org.opencontainers.image.url=https://github.com/cloudnative-pg/postgres-containers", - "index,manifest:org.opencontainers.image.source=https://github.com/cloudnative-pg/postgres-containers", + "index,manifest:org.opencontainers.image.url=${url}", + "index,manifest:org.opencontainers.image.source=${url}", "index,manifest:org.opencontainers.image.version=${pgVersion}", "index,manifest:org.opencontainers.image.revision=${revision}", - "index,manifest:org.opencontainers.image.vendor=The CloudNativePG Contributors", + "index,manifest:org.opencontainers.image.vendor=${authors}", "index,manifest:org.opencontainers.image.title=CloudNativePG PostgreSQL ${pgVersion} ${tgt}", "index,manifest:org.opencontainers.image.description=A ${tgt} PostgreSQL ${pgVersion} container image", "index,manifest:org.opencontainers.image.documentation=https://github.com/cloudnative-pg/postgres-containers", - "index,manifest:org.opencontainers.image.authors=The CloudNativePG Contributors", + "index,manifest:org.opencontainers.image.authors=${authors}", "index,manifest:org.opencontainers.image.licenses=Apache-2.0", "index,manifest:org.opencontainers.image.base.name=docker.io/library/${tag(base)}", "index,manifest:org.opencontainers.image.base.digest=${digest(base)}" ] labels = { "org.opencontainers.image.created" = "${now}", - "org.opencontainers.image.url" = "https://github.com/cloudnative-pg/postgres-containers", - "org.opencontainers.image.source" = "https://github.com/cloudnative-pg/postgres-containers", + "org.opencontainers.image.url" = "${url}", + "org.opencontainers.image.source" = "${url}", "org.opencontainers.image.version" = "${pgVersion}", "org.opencontainers.image.revision" = "${revision}", - "org.opencontainers.image.vendor" = "The CloudNativePG Contributors", + "org.opencontainers.image.vendor" = "${authors}", "org.opencontainers.image.title" = "CloudNativePG PostgreSQL ${pgVersion} ${tgt}", "org.opencontainers.image.description" = "A ${tgt} PostgreSQL ${pgVersion} container image", - "org.opencontainers.image.documentation" = "https://github.com/cloudnative-pg/postgres-containers", - "org.opencontainers.image.authors" = "The CloudNativePG Contributors", + "org.opencontainers.image.documentation" = "${url}", + "org.opencontainers.image.authors" = "${authors}", "org.opencontainers.image.licenses" = "Apache-2.0" "org.opencontainers.image.base.name" = "docker.io/library/debian:${tag(base)}" "org.opencontainers.image.base.digest" = "${digest(base)}" From d5dc9664135baaa47807a324212a4dcacefc3508 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Thu, 9 Jan 2025 17:48:54 +0100 Subject: [PATCH 03/13] docs: partial review Signed-off-by: Gabriele Bartolini --- BUILD.md | 4 +-- README.md | 80 ++++++++++++++++++++++++++++--------------------------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/BUILD.md b/BUILD.md index 1bd1228f..d0e2ebb7 100644 --- a/BUILD.md +++ b/BUILD.md @@ -40,7 +40,7 @@ The `default` target in Bake represents a Cartesian product of the following dimensions: - **Base Image** -- **Format** (e.g. `minimal` or `standard`) +- **Type** (e.g. `minimal` or `standard`) - **Platforms** - **PostgreSQL Versions** @@ -58,7 +58,7 @@ docker buildx bake --push > making testing impossible. If you want to limit the build to a specific combination, you can specify the -target in the `VERSION-FORMAT-BASE` format. For example, to build an image for +target in the `VERSION-TYPE-BASE` format. For example, to build an image for PostgreSQL 17 with the `minimal` format on the `bullseye` base image: ```bash diff --git a/README.md b/README.md index 1ea37c9e..84be5867 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,60 @@ +> **IMPORTANT:** As of January 2025, we have transitioned to a new image build +> process. 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 deprecation. + +--- + # PostgreSQL Container Images -Maintenance scripts to generate Immutable Application Containers -for all available PostgreSQL versions (13 to 17) to be used as -operands with the [CloudNativePG operator](https://cloudnative-pg.io) -for Kubernetes. +This repository provides maintenance scripts to generate immutable application +containers for all supported PostgreSQL versions (13 to 17). -## Images +These images are designed to serve as operands for the +[CloudNativePG operator](https://cloudnative-pg.io) +inside Kubernetes and are available on the +[GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). -We build three types of images: -* [system](#system) -* [minimal](#minimal) -* [standard](#standard) +Images are automatically rebuilt weekly on Mondays. -Switching from system images to minimal or standard images on an existing -cluster is not currently supported. +## Image Types -Minimal and standard images are supposed to be used alongside a backup plugin -like [Barman Cloud](https://github.com/cloudnative-pg/plugin-barman-cloud). +We currently build and support two primary types of images: -Images are available via -[GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). +- [`minimal`](#minimal) +- [`standard`](#standard) -Currently, images are automatically rebuilt once a week (Monday). +For backward compatibility, we also maintain the [`system`](#system-images) image type. -### System +> *Note:* Switching from `system` images to `minimal` or `standard` images on +> an existing cluster is not supported. -These images are built on top of the [Official Postgres image](https://hub.docker.com/_/postgres) -maintained by the [PostgreSQL Docker Community](https://github.com/docker-library/postgres), -by adding the following software: +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). + +### System Images + +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: - 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 as soon as feasible. + ### Minimal These images are build on top of [official Debian images](https://hub.docker.com/_/debian) @@ -56,25 +77,6 @@ and all the locales. Standard images include `standard` in the tag name, e.g. `17.2-standard-bookworm`. -## SBOMs - -Software Bills of Materials (SBOMs) are available for minimal and standard -images. The SBOM for an image can be retrieved with the following command: - -```shell -docker buildx imagetools inspect --format "{{ json .SBOM.SPDX}}" -``` - -## Testing image builds - -Minimal and standard image builds can be tested running bake manually. -You will need a container registry and a builder with the `docker-container` -driver. - -``` -registry= docker buildx bake --builder --push -``` - ## License and copyright This software is available under [Apache License 2.0](LICENSE). From 086b72f2cb5773ab52045876e2507c67bd30093a Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Thu, 9 Jan 2025 18:57:27 +0100 Subject: [PATCH 04/13] docs: fixes Signed-off-by: Gabriele Bartolini --- README.md | 63 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 84be5867..a2471cb2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > process. 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. +> 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 deprecation. @@ -24,17 +24,41 @@ Images are automatically rebuilt weekly on Mondays. We currently build and support two primary types of images: -- [`minimal`](#minimal) -- [`standard`](#standard) - -For backward compatibility, we also maintain the [`system`](#system-images) image type. - -> *Note:* Switching from `system` images to `minimal` or `standard` images on -> an existing cluster is not supported. +- [`minimal`](#minimal-images) +- [`standard`](#standard-images) 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). +> **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. + +### Minimal images + +Minimal images are built on top of the [official Debian images](https://hub.docker.com/_/debian), by installing [APT PostgreSQL packages](https://wiki.postgresql.org/wiki/Apt) provided by the PostgreSQL Global Development Group (PGDG). + +Minimal images include `minimal` in the tag name, e.g. `17.2-minimal-bookworm`. + + +### Standard Images + +Standard images are an extension of the `minimal` images, enhanced with the +following additional features: + +- PGAudit +- Postgres Failover Slots +- pgvector +- All Locales + +Standard images are identifiable by the `standard` tag in their names, such as: +`17.2-standard-bookworm`. + +> **Note:** Standard images are designed to offer functionality equivalent to +> the legacy `system` images when used with CloudNativePG. To achieve parity, +> 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 are based on the [Official Postgres image](https://hub.docker.com/_/postgres), maintained by the @@ -55,27 +79,10 @@ The [`Debian`](Debian) folder contains image catalogs, which can be used as: > eventually removed. Users are encouraged to migrate to `minimal` or > `standard` images as soon as feasible. -### Minimal - -These images are build on top of [official Debian images](https://hub.docker.com/_/debian) -by installing PostgreSQL. - -Minimal images include `minimal` in the tag name, e.g. -`17.2-standard-bookworm`. - -### Standard - -These images are build on top of the minimal images by adding the following -software: +## Building Images -- PGAudit -- Postgres Failover Slots -- pgvector - -and all the locales. - -Standard images include `standard` in the tag name, e.g. -`17.2-standard-bookworm`. +For detailed instructions on building PostgreSQL container images, refer to the +[BUILD.md](BUILD.md) file. ## License and copyright From 2d4ec1e621e4f419c7c8cd31c77360d167c4f6e4 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 10 Jan 2025 01:10:13 +0100 Subject: [PATCH 05/13] docs: review (wip) Signed-off-by: Gabriele Bartolini --- BUILD.md | 58 ++++++++++++++++++++++++++++++++++++++++++------------- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 90 insertions(+), 26 deletions(-) diff --git a/BUILD.md b/BUILD.md index d0e2ebb7..d0eac063 100644 --- a/BUILD.md +++ b/BUILD.md @@ -18,7 +18,7 @@ image building. 3. [Distribution Registry](https://distribution.github.io/distribution/): Formerly known as Docker Registry, to host and manage the built images. -## Verifying Requirements +### Verifying Requirements To confirm your environment is properly set up, run: @@ -26,12 +26,16 @@ To confirm your environment is properly set up, run: docker buildx bake --check ``` -If warnings appear, you may need to switch to a different build driver (e.g., -`docker-container`). Use the following commands to configure it: +If warnings appear, you may need to switch to a different build driver. For +example, use the following commands to configure a `docker-container` build +driver: ```bash -docker buildx create --driver docker-container --name docker-container -docker buildx use docker-container +docker buildx create \ + --name docker-container \ + --driver docker-container \ + --use \ + --bootstrap ``` ## Default Target @@ -59,27 +63,55 @@ 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 `bullseye` base image: +PostgreSQL 17 with the `minimal` format on the `bookworm` base image: ```bash -docker buildx bake --push postgresql-17-minimal-bullseye +docker buildx bake --push postgresql-17-minimal-bookworm ``` You can also limit the build to a single platform, for example AMD64, with: ```bash -docker buildx bake --set *.platform=linux/amd6 +docker buildx bake --push --set "*.platform=linux/amd64" ``` -## SBOMs +The two can be mixed as well: -Software Bills of Materials (SBOMs) are available for minimal and standard -images. The SBOM for an image can be retrieved with the following command: +```bash +docker buildx bake --push \ + --set "*.platform=linux/amd64" \ + postgresql-17-minimal-bookworm +``` + +## The Distribution Registry + +The images must be pushed to any registry server that complies with the **OCI +Distribution Specification**. -```shell -docker buildx imagetools inspect --format "{{ json .SBOM.SPDX}}" +By default, the build process assumes a registry server running locally at +`localhost:5000`. To use a different registry, set the `registry` environment +variable when executing the `docker` command, as shown: + +```bash +registry= docker buildx ... ``` +## Local Testing + +You can test the image-building process locally if you meet the necessary +[prerequisites](prerequisites). + +To do this, you'll need a local registry server. If you don't already have one, +you can deploy a temporary, disposable [distribution registry](https://distribution.github.io/distribution/about/deploying/) +with the following command: + +```bash +docker run -d --rm -p 5000:5000 --name registry registry:2 +``` + +This command runs a lightweight, temporary instance of the `registry:2` +container on port `5000`. + ## Trademarks *[Postgres, PostgreSQL and the Slonik Logo](https://www.postgresql.org/about/policies/trademarks/) diff --git a/README.md b/README.md index a2471cb2..89eac781 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,26 @@ --- -# PostgreSQL Container Images +# CNPG PostgreSQL Container Images -This repository provides maintenance scripts to generate immutable application -containers for all supported PostgreSQL versions (13 to 17). +This repository provides maintenance scripts for generating immutable +application containers for all supported PostgreSQL versions (13 to 17). These +containers are designed to serve as operands for the [CloudNativePG (CNPG) +operator](https://cloudnative-pg.io) in Kubernetes environments. -These images are designed to serve as operands for the -[CloudNativePG operator](https://cloudnative-pg.io) -inside Kubernetes and are available on the -[GitHub Container Registry](https://github.com/cloudnative-pg/postgres-containers/pkgs/container/postgresql). +## Key Features -Images are automatically rebuilt weekly on Mondays. +The CNPG PostgreSQL Container Images: + +- Are based on Debian Linux `stable` and `oldstable` +- Support **multi-architecture builds**, including `linux/amd64` and `linux/arm64`. +- Include **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. ## Image Types -We currently build and support two primary types of images: +We currently build and support two primary types of PostgreSQL images: - [`minimal`](#minimal-images) - [`standard`](#standard-images) @@ -34,12 +39,15 @@ plugins, such as [Barman Cloud](https://github.com/cloudnative-pg/plugin-barman- > [`system`](#system-images) image type. Switching from `system` images to > `minimal` or `standard` images on an existing cluster is not supported. -### Minimal images - -Minimal images are built on top of the [official Debian images](https://hub.docker.com/_/debian), by installing [APT PostgreSQL packages](https://wiki.postgresql.org/wiki/Apt) provided by the PostgreSQL Global Development Group (PGDG). +### Minimal Images -Minimal images include `minimal` in the tag name, e.g. `17.2-minimal-bookworm`. +Minimal images are lightweight and built on top of the +[official Debian images](https://hub.docker.com/_/debian). +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`. ### Standard Images @@ -79,6 +87,30 @@ The [`Debian`](Debian) folder contains image catalogs, which can be used as: > eventually removed. Users are encouraged to migrate to `minimal` or > `standard` images as soon as feasible. +## Build Attestations + +CNPG PostgreSQL Container Images are built with the following attestations to +ensure transparency and traceability: + +- **[Software Bill of Materials + (SBOM)](https://docs.docker.com/build/metadata/attestations/sbom/):** A + comprehensive list of software artifacts included in the image or used during + its build process, formatted using the [in-toto SPDX predicate standard](https://github.com/in-toto/attestation/blob/main/spec/predicates/spdx.md). + +- **[Provenance](https://docs.docker.com/build/metadata/attestations/slsa-provenance/):** + Metadata detailing how the image was built, following the [SLSA Provenance](https://slsa.dev) + framework. + +For example, you can retrieve the SBOM for a specific image using the following +command: + +```bash +docker buildx imagetools inspect --format "{{ json .SBOM.SPDX }}" +``` + +This command outputs the SBOM in JSON format, providing a detailed view of the +software components and build dependencies. + ## Building Images For detailed instructions on building PostgreSQL container images, refer to the From 691d11a64bb43224326335c0a5e2dc3d52c1f4b8 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 10 Jan 2025 01:19:15 +0100 Subject: [PATCH 06/13] docs: mention issue #132 Signed-off-by: Gabriele Bartolini --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 89eac781..62fde0fd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ > **IMPORTANT:** As of January 2025, we have transitioned to a new image build -> process. Previously, the images were based on the +> 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. From fbdf23d20199ff5beba19cd5a871d6476fe970a7 Mon Sep 17 00:00:00 2001 From: Marco Nenciarini Date: Fri, 10 Jan 2025 16:10:59 +0100 Subject: [PATCH 07/13] chore: set host networking in builder example Signed-off-by: Marco Nenciarini --- BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.md b/BUILD.md index d0eac063..d6271281 100644 --- a/BUILD.md +++ b/BUILD.md @@ -35,6 +35,7 @@ docker buildx create \ --name docker-container \ --driver docker-container \ --use \ + --driver-opt network=host \ --bootstrap ``` From 1a26b914ec303868cc30466e2d5dbc07fefa62da Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 10 Jan 2025 22:13:17 +0100 Subject: [PATCH 08/13] docs: review Signed-off-by: Gabriele Bartolini --- BUILD.md | 10 ++++++++-- README.md | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/BUILD.md b/BUILD.md index d6271281..893c9d81 100644 --- a/BUILD.md +++ b/BUILD.md @@ -14,7 +14,8 @@ Ensure the following tools and components are available before proceeding: 1. [Docker Buildx](https://github.com/docker/buildx): A CLI plugin for advanced image building. 2. Build Driver for Multi-Architecture Images: For example, `docker-container` -(see [Build Drivers](https://docs.docker.com/build/builders/drivers/)). +(see [Build Drivers](https://docs.docker.com/build/builders/drivers/) and +["Install QEMU Manually"](https://docs.docker.com/build/building/multi-platform/#install-qemu-manually)). 3. [Distribution Registry](https://distribution.github.io/distribution/): Formerly known as Docker Registry, to host and manage the built images. @@ -26,7 +27,7 @@ To confirm your environment is properly set up, run: docker buildx bake --check ``` -If warnings appear, you may need to switch to a different build driver. For +If errors appear, you may need to switch to a different build driver. For example, use the following commands to configure a `docker-container` build driver: @@ -39,6 +40,11 @@ docker buildx create \ --bootstrap ``` +> *Note:* This page is not intended to serve as a comprehensive guide for +> building multi-architecture images with Docker and Bake. If you encounter any +> issues, please refer to the resources listed above for detailed instructions +> and troubleshooting. + ## Default Target The `default` target in Bake represents a Cartesian product of the following diff --git a/README.md b/README.md index 62fde0fd..62d6ed46 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ > [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 deprecation. +> for backward compatibility but is planned for a future deprecation. --- @@ -86,7 +86,7 @@ The [`Debian`](Debian) folder contains image catalogs, which can be used as: > **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 as soon as feasible. +> `standard` images for new clusters as soon as feasible. ## Build Attestations From c1b1b8da9708fbd89b678578da493705090b2603 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Tue, 14 Jan 2025 11:53:53 +0100 Subject: [PATCH 09/13] fix: cosmetic Signed-off-by: Gabriele Bartolini --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 62d6ed46..0c3ecf23 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,24 @@ # CNPG PostgreSQL Container Images This repository provides maintenance scripts for generating immutable -application containers for all supported PostgreSQL versions (13 to 17). These -containers are designed to serve as operands for the [CloudNativePG (CNPG) -operator](https://cloudnative-pg.io) in Kubernetes environments. +application containers for all supported PostgreSQL versions (13 to 17). +These containers are designed to serve as operands for the +[CloudNativePG (CNPG) operator](https://cloudnative-pg.io) in Kubernetes +environments. ## Key Features The CNPG PostgreSQL Container Images: - Are based on Debian Linux `stable` and `oldstable` -- Support **multi-architecture builds**, including `linux/amd64` and `linux/arm64`. -- Include **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. +- Support **multi-architecture builds**, including `linux/amd64` and + `linux/arm64`. +- Include **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. ## Image Types @@ -70,7 +75,8 @@ Standard images are identifiable by the `standard` tag in their names, such as: ### System Images -System images are based on the [Official Postgres image](https://hub.docker.com/_/postgres), maintained by the +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: From 5d04db7dbb7889ccf03d46ec02b18d25514272d4 Mon Sep 17 00:00:00 2001 From: Marco Nenciarini Date: Fri, 10 Jan 2025 16:10:59 +0100 Subject: [PATCH 10/13] chore: add a note about host networking in builder example Signed-off-by: Marco Nenciarini --- BUILD.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BUILD.md b/BUILD.md index 893c9d81..4e4f5343 100644 --- a/BUILD.md +++ b/BUILD.md @@ -40,6 +40,9 @@ docker buildx create \ --bootstrap ``` +> *Note:* The `--driver-opt network=host` setting is required only for testing +> when you push to a distribution registry listening on `localhost`. + > *Note:* This page is not intended to serve as a comprehensive guide for > building multi-architecture images with Docker and Bake. If you encounter any > issues, please refer to the resources listed above for detailed instructions From 328537f6a9235d160fa0308e2598adcad81ba59f Mon Sep 17 00:00:00 2001 From: Francesco Canovai Date: Tue, 14 Jan 2025 17:04:32 +0100 Subject: [PATCH 11/13] fix: cosmetic Signed-off-by: Francesco Canovai --- Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 548e5319..ff7beeff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ ARG PG_MAJOR=${PG_VERSION%%.*} ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin -RUN apt-get update && \ +RUN apt-get update && \ apt-get install -y --no-install-recommends postgresql-common ca-certificates gnupg && \ /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \ apt-get install --no-install-recommends -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" postgresql-common -y && \ @@ -22,9 +22,6 @@ USER 26 FROM minimal AS standard -LABEL org.opencontainers.image.title="CloudNativePG PostgreSQL $PG_VERSION standard" -LABEL org.opencontainers.image.description="A standard PostgreSQL $PG_VERSION container image, with a minimal set of extensions and all the locales" - USER root RUN apt-get update && \ apt-get install -y --no-install-recommends locales-all \ From 260e7b62f4aecb216c5e61482499e2d4e50aca51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Tue, 14 Jan 2025 17:17:32 +0100 Subject: [PATCH 12/13] fix: uniform style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niccolò Fei --- .github/workflows/bake.yaml | 2 +- Dockerfile | 8 ++++---- docker-bake.hcl | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bake.yaml b/.github/workflows/bake.yaml index f35cf93c..84e0d600 100644 --- a/.github/workflows/bake.yaml +++ b/.github/workflows/bake.yaml @@ -60,7 +60,7 @@ jobs: - name: Generated images id: images run: | - echo "images=$(echo '${{steps.build.outputs.metadata}}' | jq -c '[ .[]."image.name" | sub(",.*";"" )]')" >> "$GITHUB_OUTPUT" + echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"" )]')" >> "$GITHUB_OUTPUT" security: name: Security checks diff --git a/Dockerfile b/Dockerfile index ff7beeff..d4f02b70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,11 +9,11 @@ ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin RUN apt-get update && \ apt-get install -y --no-install-recommends postgresql-common ca-certificates gnupg && \ /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \ - apt-get install --no-install-recommends -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" postgresql-common -y && \ + apt-get install -y --no-install-recommends -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" postgresql-common && \ sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf && \ - apt-get install --no-install-recommends \ - -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" "postgresql-${PG_MAJOR}=${PG_VERSION}*" -y && \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ + apt-get install -y --no-install-recommends \ + -o Dpkg::::="--force-confdef" -o Dpkg::::="--force-confold" "postgresql-${PG_MAJOR}=${PG_VERSION}*" && \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/* RUN usermod -u 26 postgres diff --git a/docker-bake.hcl b/docker-bake.hcl index f458ab5f..9ce8af3c 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -55,7 +55,7 @@ target "default" { target = "${tgt}" args = { PG_VERSION = "${pgVersion}" - BASE = "${base}" + BASE = "${base}" } attest = [ "type=provenance,mode=max", From 110929c0272484219136250e47bb14731f3498ab Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Wed, 15 Jan 2025 18:51:31 +0100 Subject: [PATCH 13/13] chore: cosmetic change by GFedi Signed-off-by: Gabriele Bartolini --- .github/workflows/bake.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bake.yaml b/.github/workflows/bake.yaml index 84e0d600..a32ca278 100644 --- a/.github/workflows/bake.yaml +++ b/.github/workflows/bake.yaml @@ -60,7 +60,7 @@ jobs: - name: Generated images id: images run: | - echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"" )]')" >> "$GITHUB_OUTPUT" + echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT" security: name: Security checks