Closed gertcuykens closed 1 month ago
The image is designed to allow running as any --user
; we set the permissions of directories so that works:
https://github.com/docker-library/postgres/blob/66da3846b40396249936938ee17e9684e6968a57/Dockerfile-debian.template#L10 https://github.com/docker-library/postgres/blob/66da3846b40396249936938ee17e9684e6968a57/Dockerfile-debian.template#L181 https://github.com/docker-library/postgres/blob/66da3846b40396249936938ee17e9684e6968a57/Dockerfile-debian.template#L185
I'm sorry, can you please elaborate? I just tested arbitrary user recently, and it was working OK, but maybe there's something you're doing differently that could help explain why it isn't working for you?
(If you've bind-mounted or volume-mounted a directory, it won't usually use the permissions of the directory in the image anyhow, so you'll need to also arrange to fix the permissions of your volume/directory beforehand, because without running the image as root, we can't do anything from the image to fix it for you.)
docker run --name postgres --user root --restart unless-stopped \
-e POSTGRES_PASSWORD="hello" \
-e LANG=C.UTF-8 \
-e LC_ALL=C.UTF-8 \
-v postgres:/var/lib/postgresql/data \
-v /var/run/postgresql:/var/run/postgresql \
--shm-size=128m \
--init -d postgres
This will result in a socket volume with the postgres permission id 999 from with in the container instead of the user root id 0
I expect the socket to be root (the --user) instead, thanks
Oh, running PostgreSQL itself as root is not something we or PostgreSQL support, IIRC. :grimacing:
Your best bet to play with this would be to bypass our entrypoint entirely, but last time I tried that PostgreSQL balked very loudly and early.
To illustrate:
$ docker run -it --rm --pull=always --user root --entrypoint postgres postgres
latest: Pulling from library/postgres
Digest: sha256:0aafd2ae7e6c391f39fb6b7621632d79f54068faebc726caf469e87bd1d301c0
Status: Image is up to date for postgres:latest
"root" execution of the PostgreSQL server is not permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromise. See the documentation for
more information on how to properly start the server.
Perhaps you can get closer to what you're looking for via https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-UNIX-SOCKET-GROUP and/or https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-UNIX-SOCKET-PERMISSIONS ?
ok thanks i will look into this but i assume even if you would create a --user postgres on the system then it still will be 999 right? Which always will clash with systemd-journal group on debian bookworm, because 999 is hardcoded in the Dockerfile related to the socket
So the question would boil down to if 999 can be replaced with the id from --user x ?
So the question would boil down to if 999 can be replaced with the id from --user x ?
To use any arbitrary user ID, you must provide directories with the appropriate permissions (so, whether you use a docker volume
or a local directory it might need a chown/chmod performed before being given to the postgres server container). Here is an example using local directories for data and run with my local user ID:
$ mkdir data
$ mkdir postgresql-run
$ ls -lna data/ postgresql-run/
data/:
total 8
drwxr-sr-x 2 1000 1000 4096 Jul 11 15:25 .
drwxrwsr-x 8 1000 1000 4096 Jul 11 15:25 ..
postgresql-run/:
total 8
drwxr-sr-x 2 1000 1000 4096 Jul 11 15:25 .
drwxrwsr-x 8 1000 1000 4096 Jul 11 15:25 ..
$ docker run -it --rm --name postgres \
-e POSTGRES_PASSWORD="hello" \
-e LANG=C.UTF-8 \
-e LC_ALL=C.UTF-8 \
-v "$PWD/data":/var/lib/postgresql/data \
-v "$PWD/postgresql-run":/var/run/postgresql \
--shm-size=128m \
--user 1000:1000 \
postgres
...
2024-07-11 22:26:38.215 UTC [1] LOG: database system is ready to accept connections
$ # another terminal
$ ls -lna data/ postgresql-run/
data/:
total 136
drwx------ 19 1000 1000 4096 Jul 11 15:26 .
drwxrwsr-x 8 1000 1000 4096 Jul 11 15:25 ..
drwx------ 5 1000 1000 4096 Jul 11 15:26 base
drwx------ 2 1000 1000 4096 Jul 11 15:26 global
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_commit_ts
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_dynshmem
-rw------- 1 1000 1000 5743 Jul 11 15:26 pg_hba.conf
-rw------- 1 1000 1000 2640 Jul 11 15:26 pg_ident.conf
drwx------ 4 1000 1000 4096 Jul 11 15:26 pg_logical
drwx------ 4 1000 1000 4096 Jul 11 15:26 pg_multixact
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_notify
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_replslot
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_serial
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_snapshots
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_stat
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_stat_tmp
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_subtrans
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_tblspc
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_twophase
-rw------- 1 1000 1000 3 Jul 11 15:26 PG_VERSION
drwx------ 3 1000 1000 4096 Jul 11 15:26 pg_wal
drwx------ 2 1000 1000 4096 Jul 11 15:26 pg_xact
-rw------- 1 1000 1000 88 Jul 11 15:26 postgresql.auto.conf
-rw------- 1 1000 1000 29753 Jul 11 15:26 postgresql.conf
-rw------- 1 1000 1000 36 Jul 11 15:26 postmaster.opts
-rw------- 1 1000 1000 94 Jul 11 15:26 postmaster.pid
postgresql-run/:
total 12
drwxrwsr-t 2 1000 1000 4096 Jul 11 15:26 .
drwxrwsr-x 8 1000 1000 4096 Jul 11 15:25 ..
srwxrwxrwx 1 1000 1000 0 Jul 11 15:26 .s.PGSQL.5432
-rw------- 1 1000 1000 63 Jul 11 15:26 .s.PGSQL.5432.lock
You are right, that works for me too, follow up question, can the postgres user be associated then with the --user id (in this case 1000)?
docker exec -it postgres /bin/bash
I have no name!@060c23ea2c69:/$ id
uid=1000 gid=1000 groups=1000
I have no name!@060c23ea2c69:/$ cat /etc/passwd
...
postgres:x:999:999::/var/lib/postgresql:/bin/bash
I have no name!@060c23ea2c69:/$ cat /etc/group
...
postgres:x:999:
ssl-cert:x:101:postgres
docker exec -it postgres psql -U postgres postgres
psql (16.3 (Debian 16.3-1.pgdg120+1))
Type "help" for help.
postgres=#
\q
could not save history to file "//.psql_history": No such file or directory
Maybe just add ARG UID="999"
in the Dockerfile and use $UID
where 999 is hardcoded?
No, we don't edit /etc/passwd
(especially as a non-root user) to change the ID of the postgres
user. You could provide a custom /etc/passwd
by COPY
or bind mount (read only, if using your system one) that has the user ID and name you desire. If the psql
history file is important to you then setting HOME
to a place that your custom user ID can write is the fix (like the /var/lib/postgresql
that is set for postgres
).
As for ARG UID="999"
, that would require a user to rebuild the whole postgres image to customize an ID, instead of just being FROM
it. We don't typically put that sort of customization into the Dockerfile because it just leads to code paths in the Dockerfile that we never use. We'd rather that users build FROM postgres:version
and add their customization on top.
FROM postgres:16 AS postgres16
ARG DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt update && apt upgrade -y
RUN apt install -y man-db vim curl ca-certificates && update-ca-certificates
RUN apt install -y python3-psutil postgresql-plpython3-16
RUN apt autoremove -y --purge && apt clean -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* \
&& rm -rf /var/tmp/*
RUN usermod -u 1000 postgres
RUN groupmod -g 1000 postgres
HEALTHCHECK --interval=60s --timeout=3s --retries=1 CMD pg_isready -U postgres
WORKDIR /var/lib/postgresql
USER postgres
alright good enough for me closing
Allow --user to determine all file permissions for example /var/run/postgresql not only pgdata So you can do -v of the unix socket representing the --user permissions