<p>I have a custom Container Image for postgresql and try to run this as a Stateful kubernetes application</p>
<p>The image knows 2 Volumes which are mounted into</p>
<ol>
<li><code>/opt/db/data/postgres/data</code> (the <code>$PGDATA</code> directory of my postgres intallation)</li>
<li><code>/opt/db/backup</code></li>
</ol>
<p>the backup Volume contains a deeper folder structure which is defined in the Dockerfile</p>
<h3>Dockerfile</h3>
<p>(excerpts)</p>
<pre><code>...
...
# Environment variables required for this build (do NOT change)
# -------------------------------------------------------------
...
ENV PGDATA=/opt/db/data/postgres/data
ENV PGBASE=/opt/db/postgres
...
ENV PGBACK=/opt/db/backup/postgres/backups
ENV PGARCH=/opt/db/backup/postgres/archives


# Set up user and directories
# ---------------------------
RUN mkdir -p $PGBASE $PGBIN $PGDATA $PGBACK $PGARCH &amp;&amp; \
    useradd -d /home/postgres -m -s /bin/bash --no-log-init --uid 1001 --user-group postgres &amp;&amp; \
    chown -R postgres:postgres $PGBASE $PGDATA $PGBACK $PGARCH &amp;&amp; \
    chmod a+xr $PGBASE

# set up user env
# ---------------
USER postgres
...
...
# bindings
# --------
VOLUME [&quot;$PGDATA&quot;, &quot;$DBBASE/backup&quot;]
...
...
# Define default command to start Database.
ENTRYPOINT [&quot;/docker-entrypoint.sh&quot;]
CMD [&quot;postgres&quot;, &quot;-D&quot;, &quot;/opt/db/data/postgres/data&quot;]
</code></pre>
<p>When I run this as a container or single pod in kubernetes without any <code>volumeMounts</code> all is good and the folder structure looks like it should</p>
<pre><code>find /opt/db/backup -ls
2246982      4 drwxr-xr-x   3 root     root         4096 Feb 18 09:00 /opt/db/backup
2246985      4 drwxr-xr-x   4 root     root         4096 Feb 18 09:00 /opt/db/backup/postgres
2246987      4 drwxr-xr-x   2 postgres postgres     4096 Feb 11 14:59 /opt/db/backup/postgres/backups
2246986      4 drwxr-xr-x   2 postgres postgres     4096 Feb 11 14:59 /opt/db/backup/postgres/archives
</code></pre>
<p>However once I run this based on the Statefulset below (which mounts to Volumes into the pod @ <code>/opt/db/data/postgres/data</code> &amp; <code>/opt/db/backup</code> (which includes folder structure that goes deeper then the mount point, as listed above) this is not bein carried out as intended</p>
<pre><code>find /opt/db/backup –ls
2      4 drwxr-xr-x   3 postgres postgres     4096 Feb 17 16:40 /opt/db/backup
11     16 drwx------   2 postgres postgres    16384 Feb 17 16:40 /opt/db/backup/lost+found
</code></pre>
<p><code>/opt/db/backup/postgres/backups</code> &amp; <code>/opt/db/backup/postgres/archives</code>, inherit in the Image are gone.</p>
<p>Can anybody point me to where to start looking for a solution in this?</p>
<h3>Statefulset</h3>
<pre><code>---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: postgres-stateful
  name: postgres-stateful
  labels:
    app.kubernetes.io/name: postgres
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: postgres
    app: postgres
spec:
  serviceName: &quot;postgres&quot;
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: postgres
      app.kubernetes.io/component: database
      app.kubernetes.io/part-of: postgres
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
        app.kubernetes.io/name: postgres
        app.kubernetes.io/component: database
        app.kubernetes.io/part-of: postgres
    spec:
      serviceAccountName: default
      initContainers:           # Give `postgres` user (id 1001) permissions to mounted volumes
      - name: take-volume-mounts-ownership
        image: dev-local.dev.dlz.net/postgresql:14.2-deb11
        securityContext:
          readOnlyRootFilesystem: true
        env:
          - name: &quot;PGDATA&quot;
            value: &quot;/opt/db/data/postgres/data&quot;
        command: [ &quot;/bin/sh&quot; ]
        args: [&quot;-c&quot;, &quot;chown -R 1001:1001 /opt/db/data/postgres /opt/db/backup /tmp&quot; ]
        volumeMounts:
        - name: pv-data
          mountPath: /opt/db/data/postgres
        - name: pv-backup
          mountPath: /opt/db/backup     # /opt/db/backup/postgres
        - name: emptydir-tmp
          mountPath: /tmp
      containers:
      - name: postgres
        image: dev-local.dev.dlz.net/postgresql:14.2-deb11
        imagePullPolicy: Always
        readinessProbe:
          exec:
            command: [&quot;pg_isready&quot;, &quot;-q&quot;]
          periodSeconds: 10
          initialDelaySeconds: 7
          timeoutSeconds: 2
        livenessProbe:
          exec:
            command: [&quot;psql&quot;, &quot;-q&quot;, &quot;-c&quot;, &quot;SELECT 1 WHERE 1=0&quot;]
          periodSeconds: 15
          initialDelaySeconds: 20
          timeoutSeconds: 2
        env:
          - name: &quot;PGDATA&quot;
            value: &quot;/opt/db/data/postgres/data&quot;
        envFrom:
        - configMapRef:
            name: postgres-configuration
        ports:
        - containerPort: 5432
          name: postgresdb
        resources:
          requests:
            memory: &quot;256Mi&quot;
            cpu: &quot;50m&quot;
          limits:
            memory: &quot;1Gi&quot;
            cpu: &quot;1&quot;
        securityContext:
          privileged: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1001
          allowPrivilegeEscalation: false
        volumeMounts:
        - name: pv-data
          mountPath: /opt/db/data/postgres/data   # /var/lib/postgresql/data
        - name: pv-backup
          mountPath: /opt/db/backup     # /opt/db/backup/postgres
        - name: emptydir-tmp
          mountPath: /tmp
      volumes:
      - name: pv-data
        persistentVolumeClaim:
          claimName: pgdata-ina-pvc
      - name: pv-backup
        persistentVolumeClaim:
          claimName: pgbackup-ina-pvc
      - name: emptydir-tmp
        emptyDir: {}
</code></pre>

<p>The directory which you had created in Dockerfile will be overlaid when you mount persistent volume to the same path. You can re-construct the directory structure in your &quot;take-volume-mounts-ownership&quot; container:</p>
<pre><code>...
initContainers:
- name: take-volume-mounts-ownership
  ...
  env:
  - name: PGDATA
    value: /opt/db/data/postgres/data
  - name: PGBASE
    value: /opt/db/postgres
  - name: PGBACK
    value: /opt/db/backup/postgres/backups
  - name: PGARCH
    value: /opt/db/backup/postgres/archives
  ...
  args: [&quot;-c&quot;, &quot;mkdir -p $PGBASE $PGBIN $PGDATA $PGBACK $PGARCH &amp;&amp; chown -R 1001:1001 /opt/db/data/postgres /opt/db/backup /tmp&quot; ]
  ...
</code></pre>
