├── CODEOWNERS ├── logo └── cloudnativepg.png ├── GOVERNANCE.md ├── CODE_OF_CONDUCT.md ├── image-catalogs ├── kustomization.yaml ├── README.md ├── postgis-system-trixie.yaml ├── postgis-standard-trixie.yaml ├── postgis-system-bookworm.yaml └── postgis-standard-bookworm.yaml ├── .gitignore ├── Dockerfile ├── renovate.json ├── .github └── workflows │ ├── bake.yml │ └── catalogs.yml ├── BUILD.md ├── docker-bake.hcl ├── README.md └── LICENSE /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @NiccoloFei @fcanovai @gbartolini @jbattiato @litaocdl @mnencia @sxd 2 | -------------------------------------------------------------------------------- /logo/cloudnativepg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudnative-pg/postgis-containers/HEAD/logo/cloudnativepg.png -------------------------------------------------------------------------------- /GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Governance policies 2 | 3 | Please refer to the [CloudNativePG governance policies](https://github.com/cloudnative-pg/cloudnative-pg/blob/main/GOVERNANCE.md). 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Cloud Native Postgres follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 4 | -------------------------------------------------------------------------------- /image-catalogs/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - postgis-standard-bookworm.yaml 5 | - postgis-standard-trixie.yaml 6 | - postgis-system-bookworm.yaml 7 | - postgis-system-trixie.yaml 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # editor and IDE paraphernalia 15 | .idea 16 | *.swp 17 | *.swo 18 | *~ 19 | 20 | # Testing artifacts and logs 21 | _*/ 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE=ghcr.io/cloudnative-pg/postgresql:17-standard-trixie 2 | FROM $BASE 3 | 4 | ARG PG_MAJOR 5 | ARG POSTGIS_VERSION 6 | ARG POSTGIS_MAJOR 7 | 8 | USER root 9 | 10 | RUN apt-get update && \ 11 | apt-get install -y --no-install-recommends \ 12 | "postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR=$POSTGIS_VERSION" \ 13 | "postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR-scripts" && \ 14 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ 15 | rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/* 16 | 17 | USER 26 18 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | "docker:pinDigests" 6 | ], 7 | "enabledManagers": [ 8 | "github-actions", 9 | "custom.regex" 10 | ], 11 | "customManagers": [ 12 | { 13 | "customType": "regex", 14 | "managerFilePatterns": [ 15 | "/docker-bake.hcl/" 16 | ], 17 | "matchStrings": [ 18 | "\\/\\/\\s*renovate:\\s*?(suite=(?.*?))?\\s*depName=(?.*?)?\\s*\"[A-Za-z0-9_-]+\"\\s*=\\s*\"(?.*)\"" 19 | ], 20 | "registryUrlTemplate": "https://download.postgresql.org/pub/repos/apt?suite={{#if suite}}{{suite}}{{else}}stable{{/if}}&components=main&binaryArch=amd64", 21 | "datasourceTemplate": "deb" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /image-catalogs/README.md: -------------------------------------------------------------------------------- 1 | [![CloudNativePG](../logo/cloudnativepg.png)](https://cloudnative-pg.io/) 2 | 3 | # Cluster Image Catalogs 4 | 5 | This directory contains the **official `ClusterImageCatalog` manifests** 6 | maintained by [CloudNativePG](https://cloudnative-pg.io/) for PostGIS. 7 | 8 | See the [documentation](https://cloudnative-pg.io/documentation/current/image_catalog/) 9 | for full details. 10 | 11 | ## What they are 12 | 13 | Each catalog defines the latest container images for all supported 14 | PostgreSQL/PostGIS versions. 15 | 16 | By applying a catalog, administrators ensure that CloudNativePG clusters 17 | automatically upgrade to the latest patch release within a given PostgreSQL 18 | major version. 19 | 20 | ## Usage 21 | 22 | Install a single catalog (e.g. `standard` images on Debian `trixie`): 23 | 24 | ```sh 25 | kubectl apply -f \ 26 | https://raw.githubusercontent.com/cloudnative-pg/postgis-containers/refs/heads/main/image-catalogs/postgis-standard-trixie.yaml 27 | ```` 28 | 29 | Install all catalogs at once: 30 | 31 | ```sh 32 | kubectl apply -k \ 33 | https://github.com/cloudnative-pg/postgis-containers/image-catalogs?ref=main 34 | ``` 35 | -------------------------------------------------------------------------------- /image-catalogs/postgis-system-trixie.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: ClusterImageCatalog 3 | metadata: 4 | name: postgis-system-trixie 5 | labels: 6 | images.cnpg.io/family: postgis 7 | images.cnpg.io/type: system 8 | images.cnpg.io/os: trixie 9 | images.cnpg.io/date: '20251215' 10 | images.cnpg.io/publisher: cnpg.io 11 | spec: 12 | images: 13 | - major: 13 14 | image: ghcr.io/cloudnative-pg/postgis:13.22-3.6.0-202511101009-system-trixie@sha256:a81308e173f72ac595add468e83e6976c48fd0ab81f08f9be8af87faba2fbb68 15 | - major: 14 16 | image: ghcr.io/cloudnative-pg/postgis:14.20-3.6.1-202512151010-system-trixie@sha256:839d5ebeaeee54282e0b7d65a0def983e00ac436916133821ebe0965f2f1c44a 17 | - major: 15 18 | image: ghcr.io/cloudnative-pg/postgis:15.15-3.6.1-202512151010-system-trixie@sha256:58e823653cce054455963e09c965fa763b012635d6c5da7ffe32d8a251d90376 19 | - major: 16 20 | image: ghcr.io/cloudnative-pg/postgis:16.11-3.6.1-202512151010-system-trixie@sha256:58f1e329faadf99b989f79cccb75d265b51e6af51e66e7b8024c291626be5c81 21 | - major: 17 22 | image: ghcr.io/cloudnative-pg/postgis:17.7-3.6.1-202512151009-system-trixie@sha256:3851a93fd668892cee3a9ca82b96c3096542d25c712e09c7b6426c43605c231d 23 | - major: 18 24 | image: ghcr.io/cloudnative-pg/postgis:18.1-3.6.1-202512151010-system-trixie@sha256:0266846f567d1c11f4a9063cd8b80490bcd1fe2298345a869a8f12522a1f293d 25 | -------------------------------------------------------------------------------- /image-catalogs/postgis-standard-trixie.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: ClusterImageCatalog 3 | metadata: 4 | name: postgis-standard-trixie 5 | labels: 6 | images.cnpg.io/family: postgis 7 | images.cnpg.io/type: standard 8 | images.cnpg.io/os: trixie 9 | images.cnpg.io/date: '20251215' 10 | images.cnpg.io/publisher: cnpg.io 11 | spec: 12 | images: 13 | - major: 13 14 | image: ghcr.io/cloudnative-pg/postgis:13.22-3.6.0-202511101009-standard-trixie@sha256:923659e4731551989fa8754f8e15a7fe46e4be6bc59a3c5bbb63e52d77040c9a 15 | - major: 14 16 | image: ghcr.io/cloudnative-pg/postgis:14.20-3.6.1-202512151010-standard-trixie@sha256:03513263d8d9bd3b69c08f8d66b5fe2b9b3a15469fb8447832079d4bd10b18e8 17 | - major: 15 18 | image: ghcr.io/cloudnative-pg/postgis:15.15-3.6.1-202512151010-standard-trixie@sha256:0a3f34022b44af319dd890c4cea186b1b5d55603c346fe88e1faf6f0be20c9a7 19 | - major: 16 20 | image: ghcr.io/cloudnative-pg/postgis:16.11-3.6.1-202512151010-standard-trixie@sha256:457b2c8b8e15eef7dbffd23ad9d54e9e108469a193a87d7c82368a7f0024d246 21 | - major: 17 22 | image: ghcr.io/cloudnative-pg/postgis:17.7-3.6.1-202512151009-standard-trixie@sha256:4b303f2d0ed35850203a9b0b16e779b0986edc86e67196f27f1e3ea32b815116 23 | - major: 18 24 | image: ghcr.io/cloudnative-pg/postgis:18.1-3.6.1-202512151010-standard-trixie@sha256:38106fc0b10bea00bb8d2c1f72f11fe447c64417c05c63908bd965b3c5c42f30 25 | -------------------------------------------------------------------------------- /image-catalogs/postgis-system-bookworm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: ClusterImageCatalog 3 | metadata: 4 | name: postgis-system-bookworm 5 | labels: 6 | images.cnpg.io/family: postgis 7 | images.cnpg.io/type: system 8 | images.cnpg.io/os: bookworm 9 | images.cnpg.io/date: '20251215' 10 | images.cnpg.io/publisher: cnpg.io 11 | spec: 12 | images: 13 | - major: 13 14 | image: ghcr.io/cloudnative-pg/postgis:13.22-3.6.0-202511101009-system-bookworm@sha256:9e851af742cb38dd2988d8d31d2b4ab0a117efeba637b4bb27aeef6a1e50ab5b 15 | - major: 14 16 | image: ghcr.io/cloudnative-pg/postgis:14.20-3.6.1-202512151010-system-bookworm@sha256:4fdd1809498e78db24ca09a0020e98bffd3c97be4d019466f8dbf2f68439a74f 17 | - major: 15 18 | image: ghcr.io/cloudnative-pg/postgis:15.15-3.6.1-202512151010-system-bookworm@sha256:0a09d8340bbfbad30acef628104a059ac8d418f62183c4719dbe52714b514eb4 19 | - major: 16 20 | image: ghcr.io/cloudnative-pg/postgis:16.11-3.6.1-202512151010-system-bookworm@sha256:bb0c76dfb1b24a75654dabba77ce0c86bf0d958017f804258f3d901a2ff05ccf 21 | - major: 17 22 | image: ghcr.io/cloudnative-pg/postgis:17.7-3.6.1-202512151009-system-bookworm@sha256:d8f7decfba24f5f4aa5be3ba6ea8dc8bbd83078f704a4e06ceb319f467a95182 23 | - major: 18 24 | image: ghcr.io/cloudnative-pg/postgis:18.1-3.6.1-202512151010-system-bookworm@sha256:73b4f1867c17875311f0392d793b1699418aa652ee5f57b1cdbe01419f6a14bb 25 | -------------------------------------------------------------------------------- /image-catalogs/postgis-standard-bookworm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: ClusterImageCatalog 3 | metadata: 4 | name: postgis-standard-bookworm 5 | labels: 6 | images.cnpg.io/family: postgis 7 | images.cnpg.io/type: standard 8 | images.cnpg.io/os: bookworm 9 | images.cnpg.io/date: '20251215' 10 | images.cnpg.io/publisher: cnpg.io 11 | spec: 12 | images: 13 | - major: 13 14 | image: ghcr.io/cloudnative-pg/postgis:13.22-3.6.0-202511101009-standard-bookworm@sha256:847cbe938491676be865bd895475331c66a5f4e4392144ffd9e7c131028c635b 15 | - major: 14 16 | image: ghcr.io/cloudnative-pg/postgis:14.20-3.6.1-202512151010-standard-bookworm@sha256:9590f5007030098d4342b996587f51346134a7c2b941caf4840a5d2faeaf37c4 17 | - major: 15 18 | image: ghcr.io/cloudnative-pg/postgis:15.15-3.6.1-202512151010-standard-bookworm@sha256:85e09b383ce39268e6b5af733041f4962b5345d51ab9441d5d855879d9963631 19 | - major: 16 20 | image: ghcr.io/cloudnative-pg/postgis:16.11-3.6.1-202512151010-standard-bookworm@sha256:f23746b8f036183bd3b850418841f746657b1633f3bcd8a6de7afcee91974de8 21 | - major: 17 22 | image: ghcr.io/cloudnative-pg/postgis:17.7-3.6.1-202512151009-standard-bookworm@sha256:427681980804e2505477c5c2182b023463d7bb66b65e1acec4f5cd2dd62cd16c 23 | - major: 18 24 | image: ghcr.io/cloudnative-pg/postgis:18.1-3.6.1-202512151010-standard-bookworm@sha256:03d92f6fa6b97df3bea44ca6daac1420deab917f4c8d56880375e5e6404ab45a 25 | -------------------------------------------------------------------------------- /.github/workflows/bake.yml: -------------------------------------------------------------------------------- 1 | name: Bake Images 2 | 3 | on: 4 | schedule: 5 | # Build images once a week, on Mondays 6 | - cron: 0 10 * * 1 7 | workflow_dispatch: 8 | inputs: 9 | environment: 10 | type: choice 11 | options: 12 | - testing 13 | - production 14 | default: testing 15 | description: "Choose the environment to bake the target for" 16 | 17 | permissions: {} 18 | 19 | jobs: 20 | get_versions: 21 | name: Get PostgreSQL versions 22 | runs-on: ubuntu-24.04 23 | permissions: 24 | contents: read 25 | outputs: 26 | versions: ${{ steps.get_versions.outputs.versions }} 27 | steps: 28 | - name: Checkout Code 29 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 30 | 31 | - name: Get supported PostgreSQL versions 32 | id: get_versions 33 | run: | 34 | VERSIONS="$(curl -s https://raw.githubusercontent.com/cloudnative-pg/postgres-containers/refs/heads/main/docker-bake.hcl \ 35 | | sed -n '/postgreSQL\(Versions\|PreviewVersions\) = \[/,/\]/ s/.*"\([0-9][0-9]*\)[.~][^"]*".*/\1/p' \ 36 | | sort -nu | paste -sd,)" 37 | echo "PostgreSQL versions: [$VERSIONS]" 38 | echo "versions=[$VERSIONS]" >> "$GITHUB_OUTPUT" 39 | 40 | Bake: 41 | name: Bake 42 | needs: get_versions 43 | permissions: 44 | packages: write 45 | contents: read 46 | id-token: write 47 | security-events: write 48 | strategy: 49 | fail-fast: false 50 | matrix: 51 | version: ${{ fromJson(needs.get_versions.outputs.versions) }} 52 | uses: cloudnative-pg/postgres-containers/.github/workflows/bake_targets.yml@main 53 | with: 54 | environment: ${{ github.event.inputs.environment }} 55 | postgresql_version: ${{ matrix.version }} 56 | target: "postgis" 57 | bake_files: "./source/docker-bake.hcl,./docker-bake.hcl" 58 | bake_remote_source: "cloudnative-pg/postgres-containers" 59 | secrets: 60 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 61 | 62 | Catalogs: 63 | name: Update Catalogs 64 | needs: Bake 65 | runs-on: ubuntu-24.04 66 | permissions: 67 | contents: write 68 | if: | 69 | github.ref == 'refs/heads/main' && 70 | ( github.event.inputs.environment == 'production' || github.event_name == 'schedule' ) 71 | steps: 72 | - name: Repository Dispatch 73 | uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4 74 | with: 75 | event-type: update-catalogs 76 | -------------------------------------------------------------------------------- /.github/workflows/catalogs.yml: -------------------------------------------------------------------------------- 1 | name: Update Catalogs 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: [update-catalogs] 7 | 8 | permissions: read-all 9 | 10 | defaults: 11 | run: 12 | shell: "bash -Eeuo pipefail -x {0}" 13 | 14 | jobs: 15 | update-catalogs: 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 20 | with: 21 | token: ${{ secrets.REPO_GHA_PAT }} 22 | 23 | - name: Gather supported distributions and imageTypes 24 | id: get_env 25 | run: | 26 | DISTROS=$(sed -n '/variable "distributions"/,/}/ { s/^[[:space:]]*"\([^"]*\)".*/\1/p }' docker-bake.hcl | paste -sd, -) 27 | IMAGE_TYPES=$(sed -n '/variable "imageTypes"/,/}/ { s/^[[:space:]]*"\([^"]*\)".*/\1/p }' docker-bake.hcl | paste -sd, -) 28 | echo "distributions=$DISTROS" >> "$GITHUB_OUTPUT" 29 | echo "image_types=$IMAGE_TYPES" >> "$GITHUB_OUTPUT" 30 | 31 | - name: Generate catalogs 32 | uses: cloudnative-pg/postgres-containers/.github/actions/generate-catalogs@main 33 | with: 34 | output-dir: image-catalogs/ 35 | registry: ghcr.io/cloudnative-pg/postgis 36 | family: postgis 37 | distributions: ${{ steps.get_env.outputs.distributions }} 38 | image-types: ${{ steps.get_env.outputs.image_types }} 39 | regex: '(\d+)(?:\.\d+|beta\d+|rc\d+|alpha\d+)-(\d+(?:\.\d+){1,3})-(\d{12})' 40 | 41 | - name: Diff 42 | run: | 43 | git add -A . 44 | git status 45 | git diff --staged 46 | 47 | - name: Temporarily disable "include administrators" branch protection 48 | if: ${{ always() && github.ref == 'refs/heads/main' }} 49 | id: disable_include_admins 50 | uses: benjefferies/branch-protection-bot@af281f37de86139d1c7a27b91176b5dc1c2c827c # v1.1.2 51 | with: 52 | access_token: ${{ secrets.REPO_GHA_PAT }} 53 | branch: main 54 | enforce_admins: false 55 | 56 | - uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9 57 | if: ${{ github.ref == 'refs/heads/main' }} 58 | with: 59 | add: 'image-catalogs/*.yaml' 60 | author_name: CloudNativePG Automated Updates 61 | author_email: noreply@cnpg.com 62 | message: 'chore: update imageCatalogs' 63 | 64 | - name: Enable "include administrators" branch protection 65 | uses: benjefferies/branch-protection-bot@af281f37de86139d1c7a27b91176b5dc1c2c827c # v1.1.2 66 | if: ${{ always() && github.ref == 'refs/heads/main' }} 67 | with: 68 | access_token: ${{ secrets.REPO_GHA_PAT }} 69 | branch: main 70 | enforce_admins: ${{ steps.disable_include_admins.outputs.initial_status }} 71 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # Building PostGIS Container Images for CloudNativePG 2 | 3 | This guide explains how to build PostGIS operand images for 4 | [CloudNativePG](https://cloudnative-pg.io) using 5 | [Docker Bake](https://docs.docker.com/build/bake/) together with a 6 | [GitHub Actions workflow](.github/workflows/bake.yml). 7 | 8 | ## Prerequisites 9 | 10 | This project depends on 11 | [`postgres-containers`](https://github.com/cloudnative-pg/postgres-containers). 12 | Before you begin, ensure that you have met the same prerequisites and 13 | requirements described there: 14 | 15 | - [Prerequisites](https://github.com/cloudnative-pg/postgres-containers/blob/main/BUILD.md#prerequisites) 16 | - [Verifying requirements (from the `postgres-containers` project)](https://github.com/cloudnative-pg/postgres-containers/blob/main/BUILD.md#verifying-requirements) 17 | 18 | To confirm that your environment is correctly set up for building PostGIS 19 | images, run: 20 | 21 | ```bash 22 | # The two docker-bake.hcl files are: 23 | # - the one from the upstream postgres-containers repository (remote) 24 | # - the one from this project (local), which extends/overrides the upstream file 25 | docker buildx bake --check \ 26 | -f docker-bake.hcl \ 27 | -f cwd://docker-bake.hcl \ 28 | "https://github.com/cloudnative-pg/postgres-containers.git#main" \ 29 | postgis 30 | ``` 31 | 32 | ## How It Works 33 | 34 | This repository extends the build system of 35 | [`postgres-containers`](https://github.com/cloudnative-pg/postgres-containers) 36 | by defining PostGIS as an additional build target. 37 | 38 | It achieves this by: 39 | 40 | - Including the upstream [`docker-bake.hcl`](https://github.com/cloudnative-pg/postgres-containers/blob/main/docker-bake.hcl) 41 | file as a source definition. 42 | - Extending it locally with the [`docker-bake.hcl`](docker-bake.hcl) in this 43 | repository, which adds the `postgis` target. 44 | 45 | This modular setup allows you to reuse the same configuration, overrides, and 46 | build attributes from the upstream project, while keeping PostGIS-specific 47 | settings separate and maintainable, including the supply chain. 48 | 49 | ## PostGIS Target 50 | 51 | The `postgis` target in Bake is defined as a Cartesian product of the following 52 | dimensions: 53 | 54 | - **Base Image** (e.g. `18-standard-trixie`) 55 | 56 | - **PostgreSQL major version** (e.g. `18`) 57 | - **Image type** (e.g. `standard`) 58 | - **Operating system codename** (e.g. `trixie`) 59 | - **Platforms** 60 | - **PostGIS version** 61 | 62 | # Building PostGIS Images 63 | 64 | To build all available PostGIS images, run: 65 | 66 | ```bash 67 | # The two docker-bake.hcl files are: 68 | # - the one from the upstream postgres-containers repository (remote) 69 | # - the one from this project (local), which extends/overrides the upstream file 70 | docker buildx bake --push \ 71 | -f docker-bake.hcl \ 72 | -f cwd://docker-bake.hcl \ 73 | "https://github.com/cloudnative-pg/postgres-containers.git#main" \ 74 | postgis 75 | ``` 76 | 77 | > **IMPORTANT:** Always specify the `postgis` target (or a more specific one). 78 | > If you omit the target, Bake will attempt to build all upstream targets 79 | > (including the default PostgreSQL-only images). 80 | 81 | This approach, based on 82 | [remote Bake file definitions](https://docs.docker.com/build/bake/remote-definition/), 83 | lets you combine multiple Bake files so that: 84 | 85 | - The full configuration from the upstream project is inherited. 86 | - Local overrides and PostGIS-specific settings are applied cleanly. 87 | 88 | ### Limiting the Build 89 | 90 | You can narrow down the build scope to a specific PostGIS/PostgreSQL 91 | combination using target naming conventions. 92 | 93 | PostGIS targets follow this pattern: 94 | 95 | ``` 96 | postgis---- 97 | ``` 98 | 99 | Examples: 100 | 101 | - Build all PostGIS 3 images for PostgreSQL 17: 102 | 103 | ```bash 104 | docker buildx bake \ 105 | -f docker-bake.hcl \ 106 | -f cwd://docker-bake.hcl \ 107 | "https://github.com/cloudnative-pg/postgres-containers.git#main" \ 108 | postgis-3-17* 109 | ``` 110 | 111 | - Build a specific image (PostGIS 3, PostgreSQL 17, `standard` variant, 112 | Debian Trixie): 113 | 114 | ```bash 115 | docker buildx bake \ 116 | -f docker-bake.hcl \ 117 | -f cwd://docker-bake.hcl \ 118 | "https://github.com/cloudnative-pg/postgres-containers.git#main" \ 119 | postgis-3-17-standard-trixie 120 | ``` 121 | -------------------------------------------------------------------------------- /docker-bake.hcl: -------------------------------------------------------------------------------- 1 | fullname = ( environment == "testing") ? "${registry}/postgis-testing" : "${registry}/postgis" 2 | url = "https://github.com/cloudnative-pg/postgis-containers" 3 | 4 | // MANUALLY EDIT THE CONTENT - to add new PostGIS major version 5 | variable "postgisMajorVersions" { 6 | default = [ 7 | "3" 8 | ] 9 | } 10 | 11 | // PostGIS matrix of distro x versions 12 | postgisMatrix = { 13 | bookworm = { 14 | // renovate: suite=bookworm-pgdg depName=postgis 15 | "3" = "3.6.1+dfsg-1.pgdg12+1" 16 | } 17 | trixie = { 18 | // renovate: suite=trixie-pgdg depName=postgis 19 | "3" = "3.6.1+dfsg-1.pgdg13+1" 20 | } 21 | } 22 | 23 | variable "distributions" { 24 | default = [ 25 | "bookworm", 26 | "trixie" 27 | ] 28 | } 29 | 30 | variable "imageTypes" { 31 | default = [ 32 | "standard", 33 | "system" 34 | ] 35 | } 36 | 37 | target "postgis" { 38 | matrix = { 39 | tgt = imageTypes 40 | distro = distributions 41 | postgisMajor = postgisMajorVersions 42 | pgVersion = getPgVersions(postgreSQLVersions, postgreSQLPreviewVersions) 43 | } 44 | 45 | platforms = [ 46 | "linux/amd64", 47 | "linux/arm64" 48 | ] 49 | dockerfile = "cwd://Dockerfile" 50 | context = "." 51 | name = "postgis-${postgisMajor}-${index(split(".",cleanVersion(pgVersion)),0)}-${tgt}-${distro}" 52 | tags = [ 53 | "${fullname}:${index(split(".",cleanVersion(pgVersion)),0)}-${postgisMajor}-${tgt}-${distro}", 54 | "${fullname}:${index(split(".",cleanVersion(pgVersion)),0)}-${getShortPostgisVersion(distro, postgisMajor)}-${tgt}-${distro}", 55 | "${fullname}:${cleanVersion(pgVersion)}-${getPostgisVersion(distro, postgisMajor)}-${tgt}-${distro}", 56 | "${fullname}:${cleanVersion(pgVersion)}-${getPostgisVersion(distro, postgisMajor)}-${formatdate("YYYYMMDDhhmm", now)}-${tgt}-${distro}", 57 | ] 58 | args = { 59 | PG_MAJOR = "${getMajor(pgVersion)}" 60 | POSTGIS_VERSION = "${getPostgisPackage(distro, postgisMajor)}" 61 | POSTGIS_MAJOR = postgisMajor 62 | BASE = "${getBaseImage(pgVersion, tgt, distro)}" 63 | } 64 | attest = [ 65 | "type=provenance,mode=max", 66 | "type=sbom" 67 | ] 68 | annotations = [ 69 | "index,manifest:org.opencontainers.image.created=${now}", 70 | "index,manifest:org.opencontainers.image.url=${url}", 71 | "index,manifest:org.opencontainers.image.source=${url}", 72 | "index,manifest:org.opencontainers.image.version=${pgVersion}-${getPostgisVersion(distro, postgisMajor)}", 73 | "index,manifest:org.opencontainers.image.revision=${revision}", 74 | "index,manifest:org.opencontainers.image.vendor=${authors}", 75 | "index,manifest:org.opencontainers.image.title=CloudNativePG PostGIS ${pgVersion}-${getPostgisVersion(distro, postgisMajor)} ${tgt}", 76 | "index,manifest:org.opencontainers.image.description=A ${tgt} PostGIS ${pgVersion}-${getPostgisVersion(distro, postgisMajor)} container image", 77 | "index,manifest:org.opencontainers.image.documentation=${url}", 78 | "index,manifest:org.opencontainers.image.authors=${authors}", 79 | "index,manifest:org.opencontainers.image.licenses=Apache-2.0", 80 | "index,manifest:org.opencontainers.image.base.name=${getBaseImage(pgVersion, tgt, distro)}", 81 | ] 82 | labels = { 83 | "org.opencontainers.image.created" = "${now}", 84 | "org.opencontainers.image.url" = "${url}", 85 | "org.opencontainers.image.source" = "${url}", 86 | "org.opencontainers.image.version" = "${pgVersion}", 87 | "org.opencontainers.image.revision" = "${revision}", 88 | "org.opencontainers.image.vendor" = "${authors}", 89 | "org.opencontainers.image.title" = "CloudNativePG PostGIS ${pgVersion}-${getPostgisVersion(distro, postgisMajor)} ${tgt}", 90 | "org.opencontainers.image.description" = "A ${tgt} PostGIS ${pgVersion}-${getPostgisVersion(distro, postgisMajor)} container image", 91 | "org.opencontainers.image.documentation" = "${url}", 92 | "org.opencontainers.image.authors" = "${authors}", 93 | "org.opencontainers.image.licenses" = "Apache-2.0" 94 | "org.opencontainers.image.base.name" = "${getBaseImage(pgVersion, tgt, distro)}" 95 | } 96 | } 97 | 98 | function getBaseImage { 99 | params = [ pgVersion, imageType, distro ] 100 | result = format("ghcr.io/cloudnative-pg/postgresql:%s-%s-%s", cleanVersion(pgVersion), imageType, distro) 101 | } 102 | 103 | function getPostgisPackage { 104 | params = [distro, postgisMajor] 105 | result = postgisMatrix[distro][postgisMajor] 106 | } 107 | 108 | // Gets the MM.mm.pp postgis version, e.g. "3.6.0" 109 | function getPostgisVersion { 110 | params = [ distro, postgisMajor ] 111 | result = join(".", slice(split(".", split("+", getPostgisPackage(distro, postgisMajor))[0]), 0, 3)) 112 | } 113 | 114 | // Gets the MM.mm postgis version, e.g. "3.6" 115 | function getShortPostgisVersion { 116 | params = [ distro, postgisMajor ] 117 | result = join(".", slice(split(".", split("+", getPostgisPackage(distro, postgisMajor))[0]), 0, 2)) 118 | } 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CloudNativePG](./logo/cloudnativepg.png)](https://cloudnative-pg.io/) 2 | 3 | > **IMPORTANT:** Starting from **September 2025**, the CloudNativePG project 4 | > has fully transitioned to the new Docker **`bake`-based build process** for 5 | > the main [PostgreSQL container images](https://github.com/cloudnative-pg/postgres-containers). 6 | > Consequently, the **CloudNativePG PostGIS images** will now also be built on 7 | > top of these new base images. 8 | 9 | --- 10 | 11 | # CNPG PostGIS Container Images 12 | 13 | This repository provides scripts and definitions for building **immutable 14 | application container images** that bundle PostGIS with PostgreSQL. 15 | These images are built on top of the official 16 | [CNPG PostgreSQL container images project](https://github.com/cloudnative-pg/postgres-containers) 17 | and are maintained for the latest PostGIS major version (currently 3), across 18 | all supported PostgreSQL releases, on the following base variants: 19 | 20 | - `standard` – without Barman Cloud 21 | - `system` – with Barman Cloud 22 | 23 | Images are maintained in accordance with the PostgreSQL and Debian lifecycles, 24 | following the [`postgres-containers`](https://github.com/cloudnative-pg/postgres-containers) 25 | policy—**except that Debian `oldoldstable` is not supported**—and are 26 | contingent upon the availability of 27 | [Apt packages from the PostgreSQL Global Development Group (PGDG)](https://wiki.postgresql.org/wiki/Apt). 28 | 29 | Images are available via the 30 | [`ghcr.io/cloudnative-pg/postgis` registry](https://github.com/cloudnative-pg/postgis-containers/pkgs/container/postgis), 31 | and intended exclusively as **operands of the [CloudNativePG (CNPG) operator](https://cloudnative-pg.io)** 32 | in Kubernetes environments. They are **not designed for standalone use**. 33 | 34 | > ⚠️ **IMPORTANT:** This project is transitional. The long-term plan is to 35 | > decommission it once PostgreSQL 17 reaches end of life (November 2029). 36 | > Starting with PostgreSQL 18, the `extension_control_path` GUC will allow 37 | > PostGIS to be mounted as a separate image volume, removing the need for 38 | > dedicated PostGIS container images. 39 | 40 | ## Image Tags 41 | 42 | Each image is identified by its digest and a main tag of the form: 43 | 44 | ``` 45 | MM.mm-x.y.z-TS-TYPE-OS 46 | ``` 47 | 48 | where: 49 | 50 | - `MM` is the PostgreSQL major version (e.g. `17`) 51 | - `mm` is the PostgreSQL minor version (e.g. `6`) 52 | - `x` is the PostGIS major version (e.g. `3`) 53 | - `y` is the PostGIS minor version (e.g. `6`) 54 | - `z` is the PostGIS patch version (e.g. `0`) 55 | - `TS` is the build timestamp with minute precision (e.g. `202509221231`) 56 | - `TYPE` is image type (e.g. `minimal`) 57 | - `OS` is the underlying distribution (e.g. `trixie`) 58 | 59 | For example: `postgis-testing:17.6-3.6.0-202509221231-system-trixie`. 60 | 61 | ### Rolling Tags 62 | 63 | In addition to fully qualified tags, rolling tags are available in the 64 | following formats: 65 | 66 | - `MM.mm-x.y.TYPE-OS`: latest image for a given PostgreSQL *minor* version 67 | (`17.6`) with a given PostGIS *minor* version (`3.6`) of a specific type 68 | (`minimal`) on a Debian version (`trixie`). 69 | For example: `17.6-3.6-minimal-trixie`. 70 | - `MM-x.y.TYPE-OS`: latest image for a given PostgreSQL *major* version 71 | (`17`) with a given PostGIS *minor* version (`3.6`) of a specific type 72 | (`minimal`) on a Debian version (`trixie`). 73 | For example: `17-3.6-minimal-trixie`. 74 | - `MM-x-TYPE-OS`: latest image for a given PostgreSQL *major* version (`17`) 75 | with a given PostGIS *major* version (`3`) of a specific type a specific type 76 | (`minimal`) on a Debian version (`trixie`). 77 | For example: `17-3-minimal-trixie`. 78 | 79 | ## Image Catalogs 80 | 81 | CloudNativePG publishes `ClusterImageCatalog` manifests for PostGIS in the 82 | [`image-catalogs` folder](image-catalogs), with one catalog available for each 83 | supported combination of image type and operating system version. 84 | 85 | ## License and copyright 86 | 87 | This software is available under [Apache License 2.0](LICENSE). 88 | 89 | Copyright The CloudNativePG Contributors. 90 | 91 | Licensing information of all the software included in the container images is 92 | in the `/usr/share/doc/*/copyright*` files. 93 | 94 | --- 95 | 96 |

97 | We are a Cloud Native Computing Foundation Sandbox project. 98 |

99 | 100 |

101 | 102 | 103 | 104 | CNCF logo 105 | 106 |

107 | 108 | --- 109 | 110 |

111 | CloudNativePG was originally built and sponsored by EDB. 112 |

113 | 114 |

115 | 116 | 117 | 118 | EDB logo 119 | 120 |

121 | 122 | --- 123 | 124 |

125 | Postgres, PostgreSQL, and the Slonik Logo 126 | are trademarks or registered trademarks of the PostgreSQL Community Association 127 | of Canada, and used with their permission. 128 |

129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------