Run initdb with user having write rights, but not owner of pgdata directory

I'm running initdb in docker image (official Postgres image) in Openshift environment, with sets the strict security policy, that user that will run the container will have random UID, but GID will be 0, so I can assert that the process have all necessary rights.

I've tested my container with postgres user with GID changed to 0, and everything has worked fine. The final test with ANYUID policy has caused the image to fail:

initdb: could not change permissions of directory

which is clear: the user have full write rights to the directory, but is neither owner nor root. However, I don't see WHY initdb needs to change ownership of the directory, write rights should be enough.

The initdb must be called after starting container because pgdata might be located on the volume, and anyuid policy asserts general cluster security, so I don't want to disable it. I know that it is generally possible to run Postgres docker images with that policy, because RedHat provides modified images for that, but they can be used only in OpenShift Enterprise.

How to allow initdb process to run as any user with necessary write rights, but being neither owner nor root? Does it need to recompile the sources with special flags? I've found out that RedHat is using custom packaged version of Postgres, but I haven't found out if they modified the sources...


There doesn't seem to be a straightforward solution for this issue. Looking at alternative PostgreSQL images (namely from Softwarecollections and Crunchydata), the most promising solution is not to create the pgdata dir beforehand but at runtime, when the random UID is known.

Crunchydata's Docker images make sure pgdata's parent directory is present and has enough permissions so that the random user can create a subdirectory with a random name within it at runtime. That subdirectory will then be used as pgdata and since the random user just created it, it will have him as its owner, which will make pginit happy.

As a conclusion: The official Docker image doesn't seem to be OpenShift compatible out of the box. Using Crunchydata's images (e.g. crunchydata/crunchy-postgres) instead of the official ones and mounting the volumes as pgdata's parent directory as described in their examples worked for me.

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      ...
      volumes:
        - name: pgdata
          emptyDir: {}
        - name: backup
          emptyDir: {}
      containers:
        - name: postgres
          image: "crunchydata/crunchy-postgres-gis:centos7-12.5-3.0-4.4.2"
          volumeMounts:
            - mountPath: "/pgdata"
              name: pgdata
              readOnly: false
            - mountPath: "/backup"
              name: backup
              readOnly: true
         ...

Gives e.g. /pgdata/pg-test-postgres-d9ff78d5-fb6hk as pgdata directory at runtime:

INFO: Running initdb command: initdb -D /pgdata/pg-test-postgres-d9ff78d5-fb6hk  --data-checksums > /tmp/initdb.stdout 2> /tmp/initdb.stderr

Hope this helps.