Skip to content

docker-compose: Move PGDATA to a subdir to make permissions work out-of-the-box

Emanuele Aina requested to merge wip/em/fix-permissions-out-of-the-box into master

We currently bind mount /var/lib/postgresql/data to a local folder which is assumed to exist with the right permissions, owned by the user under which the postgres container is run (uid 1000 or the one configured with the RUN_USER environment variable).

If that's not the case (on a fresh checkout, for instance), you'll be left staring at the following error, after the container failed to start:

fixing permissions on existing directory /var/lib/postgresql/data ... initdb: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted

Having things not work out of the box with weird errors is annoying and can easily lead to a non-trivial amount of wasted time (hello!).

This is because Docker creates the mount point directories as owned by root, so when the Postgres' initdb runs as the postgres user it fails to change the ownership of the directory.

Shipping the empty directory in the repository would work, but git does not really understand empty directories.

Putting a .gitignore there would make initdb complain:

initdb: directory "/var/lib/postgresql/data" exists but is not empty
It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.
Using a mount point directly as the data directory is not recommended.
Create a subdirectory under the mount point.

A solution avoiding the above issues is to ship the .gitignore to ensure the mount point directory is created with the user permissions (assuming the user doing the checkout is uid 1000 or RUN_USER is set to the right uid) and then set PGDATA to point to a subdirectory of the user-writable volume mount point, making initdb happy.

Merge request reports