Skip to content

fix(compose): mount postgres 18 volumes at /var/lib/postgresql - #412

Merged
mbryantms merged 1 commit into
mainfrom
chore/postgres-18-volume-layout
Jul 6, 2026
Merged

fix(compose): mount postgres 18 volumes at /var/lib/postgresql#412
mbryantms merged 1 commit into
mainfrom
chore/postgres-18-volume-layout

Conversation

@mbryantms

Copy link
Copy Markdown
Owner

Summary

The postgres:18 images moved PGDATA to a major-versioned subdirectory (/var/lib/postgresql/18/docker) and refuse to start when anything is mounted at the pre-18 /var/lib/postgresql/data path — bind mount, named volume, or tmpfs, even when empty (docker-library/postgres#1259; the entrypoint flags the mountpoint as an "unused mount/volume" old cluster). Since the 18-alpine bump in #347, all three compose files were affected:

  • compose.dev.yml — crash-looped against the PG17-initialized dev volume, and would keep failing even on a fresh volume because of the mount path alone. The stale "pinned back to 17" comment (from chore(docs): frontend experience audit 2026-06 + dev postgres pin #152) is replaced with the actual re-init recipe.
  • compose.prod.yml — any fresh deployment would fail the same way. Existing deployments upgrading a pre-18 volume get the entrypoint's explicit old-cluster error and need a dump/restore or pg_upgrade — probably worth a release-note when this ships.
  • compose.test.yml — the tmpfs at the old path breaks just docker-test at postgres startup. CI never caught it because the smoke compose is local-only (CI only builds the images).

All three now mount the parent /var/lib/postgresql, the layout the 18+ images require (and which keeps future pg_upgrade --link runs inside one mount).

Verification

  • Empirically confirmed the failure modes against postgres:18-alpine: empty bind mount, fresh named volume, and tmpfs at /var/lib/postgresql/data all refuse to start; tmpfs and bind mounts at /var/lib/postgresql init cleanly into 18/docker/.
  • Migrated the real dev volume with this config: pg_dumpall under a temporary PG17 container → fresh PG18 cluster on the new mount → restore. All 73 table row counts identical pre/post; dev stack healthy; app verified end-to-end against the restored data.

The postgres:18 images moved PGDATA to a major-versioned subdir
(/var/lib/postgresql/18/docker) and refuse to start when anything is
mounted at the pre-18 /var/lib/postgresql/data path — bind mount, named
volume, or tmpfs, even when empty (docker-library/postgres#1259). Since
the 18-alpine bump (#347):

- compose.dev.yml crash-looped against the PG17-initialized dev volume,
  and would keep failing even on a fresh volume because of the mount
  path. Dev volumes initialized under an older major need a
  dump/restore; the recipe is in the comment.
- compose.prod.yml would fail any fresh deployment the same way.
  Existing deployments upgrading from a pre-18 volume get the
  entrypoint's explicit old-cluster error and must dump/restore or
  pg_upgrade.
- compose.test.yml's tmpfs made 'just docker-test' fail on postgres
  startup (not caught by CI — the smoke compose is local-only; CI just
  builds the images).

All three now mount the parent /var/lib/postgresql as the 18+ images
expect. Verified locally: dev stack healthy on a restored PG17 dump
(all 73 table counts identical), and postgres:18-alpine boots clean
with tmpfs at the parent path.
@mbryantms
mbryantms merged commit 0c25bde into main Jul 6, 2026
11 checks passed
@mbryantms
mbryantms deleted the chore/postgres-18-volume-layout branch July 6, 2026 20:55
@mbryantms mbryantms mentioned this pull request Jul 6, 2026
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