This question has been asked countless times in countless places, but so far, I haven't found a single answer that actually works.
What I want:
I want to create a Docker-Container (using Docker-Compose and only a single startup without manually having to chmod or chown in between), that contains a Postgres-Database. The contents of this database should be bind-mount to my local system, eg. to the directory ./data, as would theoretically be possible using volumes:\n ./data:/var/lib/postgresql/data. If one das that, however, the ./data directory will be owned by root (or by systemd-coredump because that's the user with the id 999), and I don't want that. I want to be able to move the whole thing to another location without root-rights, so the resulting directory should be owned by my user (1000:1000).
This has been asked countless times, but no answer I tried worked. Either the directory created was empty on the host (presumably because the container didn't have rights to write as my user), or it was only accessible by root, or it would have worked with a volume (!=bind-mount), or it would have worked when chown-ing in between, but that's all not what I want.
What I found so far:
https://github.com/docker-library/postgres/issues/116: None of these solutions worked for me.
- when I eg. run
PG_DATA=$(pwd)/data docker run -d --name psql -e POSTGRES_PASSWORD=DB_PASS -e POSTGRES_USER=DB_USER -e POSTGRES_DB=DB_NAME -e PGDATA=$PG_DATA -v $PG_DATA:/var/lib/postgresql/data postgres:11.5-alpine(krzysztof-adamski's solution), the./datadirectory stays empty on my host. - shewless's solution also doesn't work:
docker run -it --rm --user "$(id -u):$(id -g)" -v $(pwd)/data:/var/lib/postgresql/data -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword -e PGDATA=/var/lib/postgresql/data/mydata postgresreturnsmkdir: cannot create directory ‘/var/lib/postgresql/data/mydata’: Permission denied- while
docker run -it --rm --user "$(id -u):$(id -g)" -v $(pwd)/data:/var/lib/postgresql/data/pgdata -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword -e PGDATA=/var/lib/postgresql/data/pgdata postgresgives me the errorchmod: changing permissions of '/var/lib/postgresql/data/pgdata': Operation not permitted chmod: changing permissions of '/var/run/postgresql': Operation not permitted The files belonging to this database system will be owned by user "chris". This user must also own the server process.. other combinations ofPGDATAand the mountpoint were also not fruitful.
https://stackoverflow.com/a/66502465/5122790:
This answer theoretically works, however I do not want to chmod in between and then change my docker-compose.yml file. There is a comment to this blogpost: https://suedbroecker.net/2020/06/23/run-a-postgressql-container-as-a-non-root-user-in-openshift/, which suggests creating a custom Dockerfile where the correct user and permissions are set, however this didn't work for me as well (...maybe because my docker-compose.yml was incompatible with that - I tried various combinations of removing/adding some lines with these files:
Dockerfile:
FROM postgres:latest
# see https://stackoverflow.com/a/66502465/5122790
RUN mkdir temp
RUN groupadd non-root-postgres-group
RUN useradd non-root-postgres-user --group non-root-postgres-group
RUN chown -R non-root-postgres-user:non-root-postgres-group /temp
RUN chmod 777 /temp
#RUN chown -R non-root-postgres-user:non-root-postgres-group /usr/local/var/postgres
USER non-root-postgres-user
docker-compose.yml:
version: "3.8"
#see https://forums.docker.com/t/data-directory-var-lib-postgresql-data-pgdata-has-wrong-ownership/17963/26
services:
sidb:
container_name: arg
# image: postgres:latest
build: . #see https://stackoverflow.com/a/66502465/5122790
volumes:
- ./django_data/db:/tmp/data:rw
- /etc/passwd:/etc/passwd:ro
ports:
- "5433:5432"
environment:
- POSTGRES_DB=siddata
- POSTGRES_USER=siddata
- POSTGRES_PASSWORD=siddata
#- PGDATA=/tmp/data #see https://stackoverflow.com/a/61884120/5122790 https://stackoverflow.com/a/66502465/5122790
#user: 1000:1000
but I didn't manage to get any of that working.
I found a ton of other answers, but NONE of them provided working code (either a pure docker-command that works on Unix (Ubuntu in my case), or a working docker-compose-file plus dockerfile if needed. There are many smart answers, maybe I'm too stupid to connect the dots, but if somebody could give me a working solution I would be vastly thankful.
Also, as far as I see it, the documentation at https://github.com/docker-library/docs/tree/master/postgres#arbitrary---user-notes even seems to be wrong - their second work-around docker run -it --rm --user "$(id -u):$(id -g)" -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword postgres does not work on my machine and again gives the error fixing permissions on existing directory /var/lib/postgresql/data ... initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted.
There are also a ton of closed issues (https://github.com/docker-library/postgres/issues/427, https://github.com/docker-library/postgres/issues/476, https://github.com/docker-library/postgres/issues/264, https://github.com/moby/moby/issues/22075, https://github.com/docker-library/postgres/issues/116) and people seem to keep figuring it out, but so far I have not found one solution that works for my demands (docker-compose, no chmoding in between, works on Linux, with a bind-mount, dir not owned by root and not empty).