Documentation is confusing in relation to setting PGDATA for older versions of PostgreSQL
The documentation says:
Users who wish to opt-in to this change on older releases can do so by setting PGDATA explicitly (--env PGDATA=/var/lib/postgresql/17/docker --volume some-postgres:/var/lib/postgresql ). To migrate pre-existing data, adjust the volume's folder structure appropriately first (moving all database files into a PG_MAJOR/docker subdirectory).
It then goes on to say:
Important Note: (for PostgreSQL 17 and below) Mount the data volume at /var/lib/postgresql/data and not at /var/lib/postgresql because mounts at the latter path WILL NOT PERSIST database data when the container is re-created. The Dockerfile that builds the image declares a volume at /var/lib/postgresql/data and if no data volume is mounted at that path then the container runtime will automatically create an anonymous volume that is not reused across container re-creations. Data will be written to the anonymous volume rather than your intended data volume and won't persist when the container is deleted and re-created.
Surely give what the second paragraph says, the first paragraph should read:
Users who wish to opt-in to this change on older releases can do so by setting PGDATA explicitly (--env PGDATA=/var/lib/postgresql/17/docker --volume some-postgres:/var/lib/postgresql/data ). To migrate pre-existing data, adjust the volume's folder structure appropriately first (moving all database files into a PG_MAJOR/docker subdirectory).
In PostgreSQL 17, the volume and PGDATA are both on /var/lib/postgresql/data. In 18+, PGDATA gets set to /var/lib/postgresql/PG_MAJOR/docker and the volume path goes down a level to /var/lib/postgresql, better matching a "standard" installation (see https://github.com/docker-library/postgres/pull/1259).
The point the documentation is trying to make is that if you want to "upgrade" to that standard layout earlier than 18+, you can do so by adjusting PGDATA and moving your persistent volume to the new path, so the documentation is correct (even if the wording could probably be improved).
With the way that is written, this:
--env PGDATA=/var/lib/postgresql/17/docker --volume some-postgres:/var/lib/postgresql
results in persistent
/mnt/point/17/docker/DB_DATA
/mnt/point/data/<empty>
anon_docker_vol on every recreate
However, if you follow the "Important note" and set PGDATA=/var/lib/postgresql/17/docker and mount /mnt/point:/var/lib/postgresql/data, ../17/docker will never be written to the persist dir getting written only into the container.
resulting in persistent
/mnt/point/data/<empty>
Seems for any version less than 18, you need PGDATA=/var/lib/postgreql/data/17/docker and mount to /mnt/point:/var/lib/postgresql/data
resulting in persistent
/mnt/point/17/docker/DB_DATA
no anon docker vol
then when one upgrades to 18 delete the PGDATA ENVAR set the mount at /mnt/point:/var/lib/postgresql
resulting in persistent
/mnt/point/17/docker/OLD_DB_DATA
/mnt/point/18/docker/NEW_DB_DATA
the "get ahead on the new structure" instructions, as written, broke my brain.