A volume that kept its old version

Moving the devcontainer to PostgreSQL 18 reused volumes that could hold PostgreSQL 16 data. The fix gives each major version its own volumes and a check that keeps them apart.

The move to PostgreSQL 18 changed the version the devcontainer asked for, but not the volumes that hold its database. Both volumes had unversioned names, and they may already have contained PostgreSQL 16 data and config from an earlier version of the environment. The new server came up pointed at that old data directory, and the cluster would not start.

What the cluster reported#

Before the fix, the cluster listing showed PostgreSQL 18 as down, with its data directory on the PostgreSQL 16 path. Starting it failed because that path was not available. After the fix, a recreated container finished its post-start step, the same listing showed PostgreSQL 18 online with its own data directory, and the version file in that directory read 18.

Versioned names, and a check for them#

Each major version now mounts its own data and config volumes, with the version in the name. The mount targets already said 18, so the change touched only the source names. The devcontainer’s test script gained a check that reads the mount list and fails if either PostgreSQL 18 volume lacks the version suffix.

What stays on disk#

The old PostgreSQL 16 volumes are not deleted, and nothing migrates them. The new cluster starts empty. For a local development database, that is the trade the change accepts: a version 18 server never reads a version 16 directory, and the old data stays on the machine until someone removes it. Reverting the mount names would restore the previous behaviour, and the old volumes would still be there to read.

A named volume outlives the image that created it, so its name is a promise about what it holds. The next database upgrade in this environment will need a new pair of names, and the check that now runs with the test script is where that promise gets enforced.