Upgrading a database container

A minor version reads the same data files: change the tag, keep the volume. A major version cannot: dump the data with the old version and restore it into the new one.

How it works

PostgreSQL 16.4 to 16.6 is a restart on the same volume. 16 to 17 changes the format on disk: pg_dump (or pg_dumpall) while 16 runs, start 17 on a new, empty volume, then load the dump with psql (pg_restore for the custom format). pg_upgrade converts in place, faster on big databases, but needs both versions' binaries in one image.

What breaks

Pointing postgres:17 at a volume written by 16 fails at start: database files are incompatible with server. Deleting the volume to get it to start loses everything. pg_dump without -d exports the database named after the user, often an empty postgres. Keep the old volume until the new version has proved itself: it is the rollback.

In a terminal

docker compose exec -T db pg_dump -U postgres -d shop > shop.sql
# compose.yaml: postgres:17 on a new volume
docker compose up -d
docker compose exec -T db psql -U postgres -d shop < shop.sql

See it break, then fix it

Write the Dockerfile or the compose file, type the docker commands, and watch a simulated server run them through reboots, upgrades and traffic. Free to start.