Skip to content

Commit 645a765

Browse files
committed
feat: add Dockerfile-supabase and rewrite Dockerfile-multigres as layered image
- Add Dockerfile-supabase: parameterised replacement for Dockerfile-15/17, selects PostgreSQL version via --build-arg PG_VERSION (default 17) - Rewrite Dockerfile-multigres: two-stage layered build on top of supabase base image; pgctld compiled from Go source (pinned to MUL-484 commit for --pg-initdb-sql-dirs support), pgbackrest added, wal-g files removed - Add docker/pgctld/pgctld wrapper script - Update ansible/vars.yml: add release_matrix_base and release_matrix_layered sections; tags derived from postgres_release via release_key at build time - Update dockerhub-release-matrix.yml and manual-docker-release.yml: split build into two sequential jobs (build_base_images then build_layered_images) so multigres is built after its base image is pushed to the registry - Update docker-image-test.yml: replace Dockerfile-15/17 matrix entries with Dockerfile-supabase; add inline base build for multigres; always pass --target production; use base_dockerfile field to discriminate layered builds - Update docker-image-test.nix and image-size-analyzer.nix: add --pg-version flag and Dockerfile-supabase support - Update README.md with new Dockerfile documentation
1 parent 4dfc110 commit 645a765

10 files changed

Lines changed: 568 additions & 535 deletions

File tree

.github/workflows/docker-image-test.yml

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,24 @@ jobs:
6161
fail-fast: false
6262
matrix:
6363
include:
64-
- { dockerfile: Dockerfile-15, target: "", name: 15 }
65-
- { dockerfile: Dockerfile-17, target: "", name: 17 }
66-
- { dockerfile: Dockerfile-orioledb-17, target: "", name: orioledb-17 }
67-
- { dockerfile: Dockerfile-multigres, target: variant-17, name: multigres-17 }
68-
- { dockerfile: Dockerfile-multigres, target: variant-orioledb-17, name: multigres-orioledb-17 }
64+
# CHANGED: Dockerfile-15/17 replaced by parameterised Dockerfile-supabase.
65+
# pg_version is passed as --build-arg PG_VERSION to select the PostgreSQL version.
66+
- dockerfile: Dockerfile-supabase
67+
name: 15
68+
pg_version: "15"
69+
- dockerfile: Dockerfile-supabase
70+
name: 17
71+
pg_version: "17"
72+
- dockerfile: Dockerfile-orioledb-17
73+
name: orioledb-17
74+
pg_version: "17"
75+
# CHANGED: base_dockerfile causes the build step to build the supabase base image
76+
# locally first and pass it as SUPABASE_IMAGE. The variant-orioledb-17 entry was
77+
# removed — that target does not exist in Dockerfile-multigres.
78+
- dockerfile: Dockerfile-multigres
79+
name: multigres-17
80+
pg_version: "17"
81+
base_dockerfile: Dockerfile-supabase
6982
steps:
7083
- name: Checkout Repo
7184
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -89,32 +102,45 @@ jobs:
89102
- name: Build Docker image
90103
run: |
91104
echo "Building ${{ matrix.name }}..."
92-
TARGET_ARG=""
93-
if [ -n "${{ matrix.target }}" ]; then
94-
TARGET_ARG="--target ${{ matrix.target }}"
105+
# CHANGED: pass PG_VERSION for Dockerfile-supabase and Dockerfile-multigres builds.
106+
PG_VERSION_ARG=""
107+
if [ -n "${{ matrix.pg_version }}" ]; then
108+
PG_VERSION_ARG="--build-arg PG_VERSION=${{ matrix.pg_version }}"
95109
fi
96-
docker build -f "${{ matrix.dockerfile }}" $TARGET_ARG \
110+
# CHANGED: layered images (multigres) need their base image available locally.
111+
# Each matrix job runs on an isolated runner, so we build the base inline here
112+
# and pass it as SUPABASE_IMAGE rather than pulling from a registry.
113+
BASE_IMAGE_ARG=""
114+
if [ -n "${{ matrix.base_dockerfile }}" ]; then
115+
docker build -f "${{ matrix.base_dockerfile }}" \
116+
--build-arg PG_VERSION=${{ matrix.pg_version }} \
117+
--target production \
118+
-t "pg-docker-test:base-${{ matrix.name }}" \
119+
.
120+
BASE_IMAGE_ARG="--build-arg SUPABASE_IMAGE=pg-docker-test:base-${{ matrix.name }}"
121+
fi
122+
docker build -f "${{ matrix.dockerfile }}" --target production $PG_VERSION_ARG $BASE_IMAGE_ARG \
97123
-t "pg-docker-test:${{ matrix.name }}" \
98124
-t "supabase-postgres:${{ matrix.name }}-analyze" \
99125
.
100126
101127
- name: Run image size analysis
102-
if: ${{ matrix.target == '' }}
128+
if: ${{ matrix.base_dockerfile == '' }}
103129
run: |
104130
echo "=== Image Size Analysis for ${{ matrix.name }} ==="
105-
nix run --accept-flake-config .#image-size-analyzer -- --image Dockerfile-${{ matrix.name }} --no-build
131+
nix run --accept-flake-config .#image-size-analyzer -- --image ${{ matrix.dockerfile }} --pg-version ${{ matrix.pg_version }} --no-build
106132
107133
- name: Run Docker image tests
108-
if: ${{ matrix.target == '' }}
134+
if: ${{ matrix.base_dockerfile == '' }}
109135
run: |
110136
echo "=== Running tests for ${{ matrix.name }} ==="
111-
nix run --accept-flake-config .#docker-image-test -- --no-build Dockerfile-${{ matrix.name }}
137+
nix run --accept-flake-config .#docker-image-test -- --no-build --pg-version ${{ matrix.pg_version }} ${{ matrix.dockerfile }}
112138
113139
- name: Run multigres Docker image tests
114-
if: ${{ matrix.target != '' }}
140+
if: ${{ matrix.base_dockerfile != '' }}
115141
run: |
116142
echo "=== Running tests for ${{ matrix.name }} ==="
117-
nix run --accept-flake-config .#docker-image-test -- --no-build --target ${{ matrix.target }} ${{ matrix.dockerfile }}
143+
nix run --accept-flake-config .#docker-image-test -- --no-build --target production ${{ matrix.dockerfile }}
118144
119145
- name: Show container logs on failure
120146
if: failure()
@@ -130,6 +156,7 @@ jobs:
130156
run: |
131157
docker ps -a --filter "name=pg-test-${{ matrix.name }}" -q | xargs -r docker rm -f || true
132158
docker rmi "pg-docker-test:${{ matrix.name }}" || true
159+
docker rmi "pg-docker-test:base-${{ matrix.name }}" || true # CHANGED: remove ephemeral base image built for layered builds
133160
docker rmi "supabase-postgres:${{ matrix.name }}-analyze" || true
134161
135162
skip-notification:

.github/workflows/dockerhub-release-matrix.yml

Lines changed: 58 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -19,52 +19,29 @@ jobs:
1919
runs-on: blacksmith-4vcpu-ubuntu-2404
2020
outputs:
2121
matrix_config: ${{ steps.set-matrix.outputs.matrix_config }}
22+
base_matrix: ${{ steps.set-matrix.outputs.base_matrix }}
23+
layered_matrix: ${{ steps.set-matrix.outputs.layered_matrix }}
2224
steps:
2325
- name: Checkout Repo
2426
uses: supabase/postgres/.github/actions/shared-checkout@HEAD
2527
- uses: ./.github/actions/nix-install-ephemeral
2628
- name: Generate build matrix
2729
id: set-matrix
2830
run: |
29-
nix run nixpkgs#nushell -- -c 'let versions = (open ansible/vars.yml | get postgres_major)
30-
let base_matrix = ($versions | each { |ver|
31-
let version = ($ver | str trim)
32-
let dockerfile = $"Dockerfile-($version)"
33-
if ($dockerfile | path exists) {
34-
{
35-
version: $version,
36-
dockerfile: $dockerfile,
37-
target: "production"
38-
}
39-
} else {
40-
null
41-
}
42-
} | compact)
43-
44-
# Discover multigres variants by checking for matching targets in Dockerfile-multigres
45-
let multigres_matrix = ($versions | each { |ver|
46-
let version = ($ver | str trim)
47-
let mg_version = $"multigres-($version)"
48-
let mg_dockerfile = "Dockerfile-multigres"
49-
let mg_target = $"variant-($version)"
50-
if ($mg_dockerfile | path exists) and (open --raw $mg_dockerfile | str contains $"AS ($mg_target)") {
51-
{
52-
version: $mg_version,
53-
dockerfile: $mg_dockerfile,
54-
target: $mg_target
55-
}
56-
} else {
57-
null
58-
}
59-
} | compact)
60-
61-
let matrix = ($base_matrix | append $multigres_matrix)
62-
63-
let matrix_config = {
64-
include: $matrix
65-
}
66-
67-
$"matrix_config=($matrix_config | to json -r)" | save --append $env.GITHUB_OUTPUT'
31+
nix run nixpkgs#nushell -- -c '
32+
let releases = (open ansible/vars.yml | get postgres_release)
33+
let base = (open ansible/vars.yml | get release_matrix_base
34+
| each { |e| $e | insert tag ($releases | get $e.release_key) })
35+
let layered = (open ansible/vars.yml | get release_matrix_layered
36+
| each { |e|
37+
let ver = ($releases | get $e.release_key)
38+
$e | insert tag $"($ver)($e.tag_suffix)" | insert base_tag $ver
39+
})
40+
let combined = ($base | append $layered)
41+
$"base_matrix=({include: $base} | to json -r)" | save --append $env.GITHUB_OUTPUT
42+
$"layered_matrix=({include: $layered} | to json -r)" | save --append $env.GITHUB_OUTPUT
43+
$"matrix_config=({include: $combined} | to json -r)" | save --append $env.GITHUB_OUTPUT
44+
'
6845
build:
6946
needs: prepare
7047
strategy:
@@ -89,11 +66,11 @@ jobs:
8966
| str join "\n"
9067
| save --append $env.GITHUB_OUTPUT
9168
'
92-
build_release_image:
69+
build_base_images:
9370
needs: [prepare, build]
9471
strategy:
9572
matrix:
96-
postgres: ${{ fromJson(needs.prepare.outputs.matrix_config).include }}
73+
postgres: ${{ fromJson(needs.prepare.outputs.base_matrix).include }}
9774
arch: [amd64, arm64]
9875
runs-on: ${{ matrix.arch == 'amd64' && 'large-linux-x86' || 'large-linux-arm' }}
9976
timeout-minutes: 180
@@ -109,52 +86,56 @@ jobs:
10986
with:
11087
username: ${{ secrets.DOCKER_USERNAME }}
11188
password: ${{ secrets.DOCKER_PASSWORD }}
112-
- name: Get image tag
113-
id: image
114-
run: |
115-
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
116-
pg_version=$(nix run nixpkgs#nushell -- -c '
117-
let version = "${{ matrix.postgres.version }}"
118-
let is_multigres = ($version | str starts-with "multigres-")
119-
let base_version = if $is_multigres { $version | str replace "multigres-" "" } else { $version }
120-
let release_key = if ($base_version | str contains "orioledb") {
121-
$"postgresorioledb-17"
122-
} else {
123-
$"postgres($base_version)"
124-
}
125-
let base_tag = (open ansible/vars.yml | get postgres_release | get $release_key | str trim)
126-
if $is_multigres { $"($base_tag)-multigres" } else { $base_tag }
127-
')
128-
echo "pg_version=supabase/postgres:$pg_version" >> $GITHUB_OUTPUT
129-
else
130-
pg_version=$(nix run nixpkgs#nushell -- -c '
131-
let version = "${{ matrix.postgres.version }}"
132-
let is_multigres = ($version | str starts-with "multigres-")
133-
let base_version = if $is_multigres { $version | str replace "multigres-" "" } else { $version }
134-
let release_key = if ($base_version | str contains "orioledb") {
135-
$"postgresorioledb-17"
136-
} else {
137-
$"postgres($base_version)"
138-
}
139-
let base_tag = (open ansible/vars.yml | get postgres_release | get $release_key | str trim)
140-
if $is_multigres { $"($base_tag)-multigres" } else { $base_tag }
141-
')
142-
echo "pg_version=supabase/postgres:$pg_version" >> $GITHUB_OUTPUT
143-
fi
14489
- id: build
14590
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
14691
with:
14792
push: true
14893
build-args: |
14994
${{ needs.build.outputs.build_args }}
95+
PG_VERSION=${{ matrix.postgres.pg_version }}
15096
target: ${{ matrix.postgres.target }}
151-
tags: ${{ steps.image.outputs.pg_version }}_${{ matrix.arch }}
97+
tags: supabase/postgres:${{ matrix.postgres.tag }}_${{ matrix.arch }}
98+
platforms: linux/${{ matrix.arch }}
99+
cache-from: type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
100+
cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
101+
file: ${{ matrix.postgres.dockerfile }}
102+
103+
build_layered_images:
104+
needs: [prepare, build, build_base_images]
105+
strategy:
106+
matrix:
107+
postgres: ${{ fromJson(needs.prepare.outputs.layered_matrix).include }}
108+
arch: [amd64, arm64]
109+
runs-on: ${{ matrix.arch == 'amd64' && 'large-linux-x86' || 'large-linux-arm' }}
110+
timeout-minutes: 180
111+
steps:
112+
- name: Checkout Repo
113+
uses: supabase/postgres/.github/actions/shared-checkout@HEAD
114+
- uses: ./.github/actions/nix-install-ephemeral
115+
- run: docker context create builders
116+
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
117+
with:
118+
endpoint: builders
119+
- uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
120+
with:
121+
username: ${{ secrets.DOCKER_USERNAME }}
122+
password: ${{ secrets.DOCKER_PASSWORD }}
123+
- id: build
124+
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
125+
with:
126+
push: true
127+
build-args: |
128+
${{ needs.build.outputs.build_args }}
129+
PG_VERSION=${{ matrix.postgres.pg_version }}
130+
SUPABASE_IMAGE=supabase/postgres:${{ matrix.postgres.base_tag }}_${{ matrix.arch }}
131+
target: ${{ matrix.postgres.target }}
132+
tags: supabase/postgres:${{ matrix.postgres.tag }}_${{ matrix.arch }}
152133
platforms: linux/${{ matrix.arch }}
153134
cache-from: type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
154135
cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
155136
file: ${{ matrix.postgres.dockerfile }}
156137
merge_manifest:
157-
needs: [prepare, build, build_release_image]
138+
needs: [prepare, build, build_base_images, build_layered_images]
158139
strategy:
159140
matrix:
160141
include: ${{ fromJson(needs.prepare.outputs.matrix_config).include }}
@@ -170,20 +151,7 @@ jobs:
170151
password: ${{ secrets.DOCKER_PASSWORD }}
171152
- name: Get image tag
172153
id: get_version
173-
run: |
174-
nix run nixpkgs#nushell -- -c '
175-
let version = "${{ matrix.version }}"
176-
let is_multigres = ($version | str starts-with "multigres-")
177-
let base_version = if $is_multigres { $version | str replace "multigres-" "" } else { $version }
178-
let release_key = if ($base_version | str contains "orioledb") {
179-
$"postgresorioledb-17"
180-
} else {
181-
$"postgres($base_version)"
182-
}
183-
let base_tag = (open ansible/vars.yml | get postgres_release | get $release_key | str trim)
184-
let pg_version = if $is_multigres { $"($base_tag)-multigres" } else { $base_tag }
185-
$"pg_version=supabase/postgres:($pg_version)" | save --append $env.GITHUB_OUTPUT
186-
'
154+
run: echo "pg_version=supabase/postgres:${{ matrix.tag }}" >> $GITHUB_OUTPUT
187155
- name: Output version
188156
id: output_version
189157
run: |
@@ -195,7 +163,7 @@ jobs:
195163
- name: Upload Results Artifact
196164
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
197165
with:
198-
name: merge_results-${{ matrix.version }}
166+
name: merge_results-${{ matrix.tag }}
199167
path: results.txt
200168
if-no-files-found: warn
201169
- name: Merge multi-arch manifests

0 commit comments

Comments
 (0)