2

I'm trying to create PostgreSQL container with bind mounted host directory in it as the PostgreSQL data directory. Doing it according to official PostgreSQL docker image documentation and Example from Postres docker-library but stuck on error about initdb changing permissions.

$ ls -lan instance01/ total 8 drwxr-xr-x. 2 1004 1004 4096 Oct 13 23:49 . drwx------. 7 1004 1004 4096 Oct 14 00:00 .. 

passwd and group files are copied out from the image container and modified to add 1004:1004 as follows:

$ cat passwd_pg root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin _apt:x:42:65534::/nonexistent:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin postgres:x:999:999::/var/lib/postgresql:/bin/bash foo:x:1004:1004::/var/lib/postgresql:/bin/bash $ cat group_pg root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24: floppy:x:25: tape:x:26: sudo:x:27: audio:x:29: dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: shadow:x:42: utmp:x:43: video:x:44: sasl:x:45: plugdev:x:46: staff:x:50: games:x:60: users:x:100: nogroup:x:65534: postgres:x:999:foo foo:x:1004:foo ssl-cert:x:101:postgres 

User and group:

$ echo $(id -u):$(id -g) 1004:1004 

Now creating the container:

$ podman container create --name postgres-instance01 -e POSTGRES_PASSWORD=test -p 5433:5432 --user $(id -u):$(id -g) --mount type=bind,relabel=private,ro=true,src=/home/foo/passwd_pg,dst=/etc/passwd --mount type=bind,ro=true,src=/home/foo/group_pg,dst=/etc/group,relabel=private --mount type=bind,src="/home/foo/instance01",relabel=private,dst=/var/lib/postgresql/data postgres:15 

But when trying to run it the error shows:

$ podman container start -ai postgres-instance01 chmod: changing permissions of '/var/lib/postgresql/data': 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 "foo". This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /var/lib/postgresql/data ... initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted 
1
  • That's probably (not in a location where I can test right now) because /var/lib/postgresql/data is the mount point. You'll have to state the desired permissions and uid/gid during the mount phase rather than later. Commented Oct 15 at 7:46

1 Answer 1

1

Adding the --userns=keep-id flag to your podman container create command solves the issue.

By default, rootless Podman containers operate within a user namespace. This means that your user ID (UID) and group ID (GID) on the host system are mapped to a different set of UIDs and GIDs inside the container. Typically, your host user is mapped to the root user (UID 0) inside the container.

Knowing this, using --user $(id -u):$(id -g) will not be enough. The process inside the container, running as what it thinks is your UID, is actually a different user from the host's perspective. When this process then tries to run chmod on the bind-mounted host directory, the kernel denies the operation because the actual owner of the directory is your host user, not the subordinate user the container process is running as.

And that's when --userns=keep-id kicks in. This flag simply makes sure that your host user's UID and GID are mapped to the exact same UID and GID inside the container.

Because the UIDs are now identical from the kernel's perspective, the initdb process running as 1004 inside the container has the correct ownership and permissions to read, write, and modify the instance01 directory mounted at /var/lib/postgresql/data.

And so, running with this flag, I got

podman container create --name postgres-instance01 -e POSTGRES_PASSWORD=test -p 5433:5432 --user $(id -u):$(id -g) --mount type=bind,relabel=private,ro=true,src=$PWD/passwd_pg,dst=/etc/passwd --mount type=bind,relabel=private,ro=true,src=$PWD/group_pg,dst=/etc/group --mount type=bind,relabel=private,src=$PWD/instance01,dst=/var/lib/postgresql/data --replace --userns=keep-id docker.io/library/postgres:15 0532053ac69c55153ef2cc07da9a1ea5170ea2b8a7329f5d3645685eafd6779a podman container start -ai postgres-instance01 chmod: changing permissions of '/var/run/postgresql': Operation not permitted 2025-10-15 07:50:12.229 UTC [1] LOG: starting PostgreSQL 15.14 (Debian 15.14-1.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit 2025-10-15 07:50:12.230 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 2025-10-15 07:50:12.230 UTC [1] LOG: listening on IPv6 address "::", port 5432 2025-10-15 07:50:12.245 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2025-10-15 07:50:12.258 UTC [16] LOG: database system was shut down at 2025-10-15 07:45:43 UTC 2025-10-15 07:50:12.266 UTC [1] LOG: database system is ready to accept connections 

The message chmod: changing permissions of '/var/run/postgresql': Operation not permitted is not fatal and will not stop podman to start. I can't continue to test right now but it is most likely because in the official PostgreSQL docker image, directories like /var/run/postgresql are created and owned by the postgres user, which has a standard UID of 999 creating a mismatch with your UID of 1004.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.