Skip to content

feat: add Dockerfile-supabase and rework Dockerfile-multigres as layered images#2160

Open
mkindahl wants to merge 1 commit into
developfrom
feat/dockerfile-refactor
Open

feat: add Dockerfile-supabase and rework Dockerfile-multigres as layered images#2160
mkindahl wants to merge 1 commit into
developfrom
feat/dockerfile-refactor

Conversation

@mkindahl
Copy link
Copy Markdown

@mkindahl mkindahl commented May 20, 2026

Add Dockerfile-supabase and rewrite Dockerfile-multigres as a layered image

Summary

The existing Dockerfile-15 and Dockerfile-17 are near-identical files that diverge only in a handful of version-specific lines. This PR introduces Dockerfile-supabase, a single parameterised Dockerfile that replaces both, selectable via --build-arg PG_VERSION=15|17 (default 17). It also rewrites Dockerfile-multigres from a self-contained Nix-based build into a thin layered image built on top of Dockerfile-supabase, which significantly reduces duplication and makes the multigres image easier to keep in sync with the base.

Dockerfile-15, Dockerfile-17, and Dockerfile-orioledb-17 are unchanged and remain in the repo. Dockerfile-supabase replaces Dockerfile-15 and Dockerfile-17 in the release workflows; Dockerfile-orioledb-17 continues to be built via release_matrix_layered.

Changes

Dockerfile-supabase (new)

Parameterised replacement for Dockerfile-15 and Dockerfile-17. The three-stage structure (nix-builder, gosu-builder, production) is identical to the existing files. Version-specific differences (stripping timescaledb/plv8, commenting out db_user_namespace) are gated on [ "$PG_VERSION" -ge 17 ] at build time.

# Build for PostgreSQL 17 (default)
docker build -f Dockerfile-supabase -t supabase-postgres:17 -t supabase-postgres:17.

# Build for PostgreSQL 15
docker build -f Dockerfile-supabase --build-arg PG_VERSION=15 -t supabase-postgres:15 .

Dockerfile-multigres (rewritten)

Reduced from ~320 lines to ~70. A pgctld-builder stage compiles pgctld from Go source, pinned to the commit that introduced --pg-initdb-sql-dirs (MUL-484). The final stage does FROM ${SUPABASE_IMAGE} AS production, adding pgbackrest, the pgctld binary and wrapper script, a config template, and removing inherited wal-g files. The base image is overridable via --build-arg SUPABASE_IMAGE.

The old Dockerfile had separate variant-17 and variant-orioledb-17 final stages, selected via --target. These are replaced by a single production stage — consistent with all other Dockerfiles. The variant-orioledb-17 target is removed entirely; a multigres image layered on top of OrioleDB is not built in this PR (the standalone Dockerfile-orioledb-17 image continues to be built via release_matrix_layered). All Dockerfiles now use production as the final stage name, so --target production is passed unconditionally by the workflows and test scripts.

# Build supabase base, then multigres on top
docker build -f Dockerfile-supabase -t supabase-postgres:17 .
docker build -f Dockerfile-multigres -t multigres:17 .

# Override the base image
docker build -f Dockerfile-multigres \
    --build-arg SUPABASE_IMAGE=registry.example.com/supabase-postgres:17 \
    -t multigres:17 .

docker/pgctld/pgctld (new, replaces docker/pgctld/pgctld-wrapper)

Wrapper script installed at /usr/local/bin/pgctld that injects --postgres-config-template and --pg-initdb-sql-dirs on every pgctld call, so Kubernetes manifests work without extra flags.

The old pgctld-wrapper also created a symlink /var/log/postgresql/postgresql.json -> /proc/1/fd/1 to bridge PostgreSQL's JSON log file to the container's stdout (for kubelet + Vector, introduced in commit 9313c070). This log-bridging is not carried over to the new wrapper. Whether pgctld itself now handles stdout logging needs to be confirmed before merging.

ansible/vars.yml

vars.yml is now the single source of truth for which images are built and how they are tagged. Two new sections are added:

  • release_matrix_base — lists the base Dockerfiles to build (currently Dockerfile-supabase at pg15 and pg17)
  • release_matrix_layered — lists the layered Dockerfiles to build on top of them (currently Dockerfile-multigres and Dockerfile-orioledb-17)

Each entry carries a release_key that maps to a full version string in postgres_release, and an optional tag_suffix (e.g. -multigres). Image tags are derived entirely from these fields at workflow runtime — nothing is hardcoded in the workflow files themselves. To add a new version or change a tag, only vars.yml needs to be updated.

Release workflows (dockerhub-release-matrix.yml, manual-docker-release.yml)

The release flow is split into two phases: build_base_images builds and pushes the supabase base images first, then build_layered_images builds images that depend on them. Strictly speaking, the OrioleDB image is not a layered image since it builds a patched version of Postgres inside the Dockerfile, but logically it is a layered image (if all patches were accepted into Postgres, it would be a pure layered image) and is therefore treated as one.

The prepare job now reads the explicit matrix from vars.yml rather than scanning the filesystem for Dockerfiles and inspecting their stage names. The single build_release_image job is replaced by two sequential jobs:

  • build_base_images — runs first, pushes base images to the registry
  • build_layered_images — depends on build_base_images, passes SUPABASE_IMAGE=supabase/postgres:<base_tag>_<arch> as a build arg

This ordering is required because Dockerfile-multigres is now a FROM reference to the base image rather than a self-contained build. Tag computation in merge_manifest is simplified from a ~15-line Nushell script per entry to a single echo, since tags are precomputed in prepare.

docker-image-test.yml

  • Matrix entries for Dockerfile-15 and Dockerfile-17 replaced by two Dockerfile-supabase entries with pg_version: "15"/"17"
  • multigres-17 entry gains base_dockerfile: Dockerfile-supabase, which triggers an inline base build before the layered build (each test runner has an isolated Docker daemon with no shared registry)
  • --target production is now hardcoded — all Dockerfiles use a production final stage
  • multigres-orioledb-17 entry removed — that target no longer exists in Dockerfile-multigres

nix/packages/docker-image-test.nix, nix/packages/image-size-analyzer.nix

Both gain a --pg-version flag so they can pass --build-arg PG_VERSION when building or analyzing Dockerfile-supabase.

Testing

The existing docker-image-test suite runs SQL regression tests against a live container for each matrix entry. The CI workflow now runs it against:

  • Dockerfile-supabase at pg15 and pg17 (replacing the former Dockerfile-15 / Dockerfile-17 entries)
  • Dockerfile-multigres (multigres-17), with Dockerfile-supabase built inline as the base

Dockerfile-orioledb-17 tests are unchanged.

Fixes MUL-483

@mkindahl mkindahl requested review from a team as code owners May 20, 2026 09:29
Comment thread Dockerfile-supabase Outdated
@mkindahl mkindahl force-pushed the feat/dockerfile-refactor branch from 1ed9ea8 to a9551ce Compare May 21, 2026 12:09
…ered 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
@mkindahl mkindahl force-pushed the feat/dockerfile-refactor branch from a9551ce to 8a8de35 Compare May 26, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant