I recently had to delete all Docker containers on my system, and when VSCode rebuilt my Java devcontainer with PostgreSQL, it wouldn't start. I get the following error in the logs:
PostgreSQL Database directory appears to contain a database; Skipping initialization
2023-11-07 20:27:40.074 UTC  FATAL: database files are incompatible with server
2023-11-07 20:27:40.074 UTC  DETAIL: The data directory was initialized by PostgreSQL version 15, which is not compatible with this version 16.0 (Debian 16.0-1.pgdg120+1).
I assume this is because the new image is using the database from the old image. Where exactly is this database stored, and how do I get rid of it if it's still there after
docker system prune --all --force --volumes?
It appears that you have a volume that contains a PostgreSQL instance that is compatible with v. 15, but you are trying to load it up with a
postgres:16 image. This is not possible, as data directories are not immediately compatible with newer versions of Postgres. Even without Docker, moving from an older database instance/cluster to a newer database binary requires either 1) dump/reload or 2) use of
pg_upgrade. Some options below:
You mentioned that you have 3
.yml files -- you'll need to look under the
volumes: section of the service corresponding to
postgres:##. Without knowing the actual directory mapping, I cannot 100% help you. However, since we know that you did
docker system prune --all --force --volumes and the data is still there, then we know that the data you're trying to overwrite is not in a Docker Volume, but probably some directory mapping to your host machine. Once you identify which directory that is, you can either 1) delete the mapping from the
.yml file or 2) delete the contents of the mapped folder
The work around the issue quickly, just change from using a
postgres:16 image to a
postgres:15 image in your
postgres:15 image to call
pg_dump against the database cluster will result in a logical/plaintext dump of your database. With this dump, you can start up a
postgres:16 image with a new Docker Volume, and then use
psql to copy the contents of the dump into the new database
Note: This is a lot more complex, and requires a bit of advanced knowledge of how the containers work.
pg_upgrade, you'll need to use a
postgres:15 image (preferably running on a Debian/Ubuntu underlying OS). You'll need to use
apt to install Postgres 16, and then use
pg_upgrade to upgrade the data directory. After that, you can tear down the container, and use a
postgres:16 container to access and serve up the now-updated data cluster.