Upgrading Postgres Docker containers

This is a follow up to my old post from 2018: Upgrade Postgres Container to Version 10

In the meanwhile, I upgraded every year my Docker containers to the newest version of Postgres and realized, I can further optimize that process. But first, let's take a step back. Why not just pull the latest image and mount the existing directory? This works with minor version upgrades, but not major ones. If you do this with a major version upgrade, you'll see the following error:

FATAL:   database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.2.

These are the new step-by-step upgrade instructions:

Preconditions

For sake of simplicity, I assume the following things:

  • You are using either the official Postgres docker image or an image similar in configuration.
  • You are mounting /var/lib/postgresql/data onto your disc.

How-To:

  1. Stop any application accessing the database, you want to do this, to guarantee a consistent state.
  2. Create a dump using docker exec POSTGRES_CONTAINER pg_dumpall -U postgres > dump.sql. This will be stored on your local disc, so you'll be safe to stop and possibly remove the container.
  3. Stop the container. Optionally, back up the directory, after you stopped the container.
  4. Start the new container using the new Postgres image. I prefer to mount a new directory for the data. In case you want to reuse the same directory, make sure you created a backup in step 3. The mounted directory must be empty, otherwise, you'd see the aforementioned error message in the docker logs, and the container would be crashing.
  5. I assume the new Postgres container is successfully up and running, but empty. So we need to import the data again. To do this, simply run docker exec -i POSTGRES_CONTAINER psql -U postgres < dump.sql
  6. Now you can start the application again, and your upgrade should be complete.

Happy coding!