<p>I am trying to run <a href="https://learn.getgrav.org/16/basics/installation" rel="nofollow noreferrer">Grav CMS</a> on Kubernetes. However I am running into a permissions problem. Grav is not able to write to the mounted volume.</p>

<p>These are the relevant object definitions. The latest version of Grav is already extracted to the persistent volume bound to <code>grav-data</code>.</p>

<pre><code># pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  volumes:
    - name: shared-files
      persistentVolumeClaim:
        claimName: grav-data
    - name: nginx-config-volume
      configMap:
        name: nginx-config
  containers:
    - name: app
      image: php:7.4-fpm
      imagePullPolicy: Always
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html
    - name: nginx
      image: nginx:1.7
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html
        - name: nginx-config-volume
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
    - name: tty      
      image: busybox:latest
      command: [ "/bin/sh", "-c", "sleep 6000" ]
      volumeMounts:
        - name: shared-files
          mountPath: /var/www/html



---

# configMap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {}
    http {
      error_log /dev/stdout info;
      server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        root /var/www/html;
        index index.php;
        location / {
            try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
          include fastcgi_params;
          fastcgi_param REQUEST_METHOD $request_method;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_pass 127.0.0.1:9000;
        }
      }
    }
</code></pre>

<p>From the definitions above, php-fpm should be running as root. But when I exec into the busybox container </p>

<pre><code>$ k exec -it --container=tty web
$ wget -O - localhost
Connecting to localhost (127.0.0.1:80)
writing to stdout
&lt;br /&gt;
&lt;b&gt;Fatal error&lt;/b&gt;:  Uncaught RuntimeException: Creating directory failed for /var/www/html/cache/compiled/files/40779d000b68629af00dd987148afc06.yaml.php in /var/www/html/ve
ndor/rockettheme/toolbox/File/src/File.php:325
Stack trace:
#0 /var/www/html/vendor/rockettheme/toolbox/File/src/PhpFile.php(31): RocketTheme\Toolbox\File\File-&amp;gt;save(Array)
#1 /var/www/html/system/src/Grav/Common/File/CompiledFile.php(65): RocketTheme\Toolbox\File\PhpFile-&amp;gt;save(Array)
#2 /var/www/html/system/src/Grav/Common/Config/Setup.php(215): Grav\Common\File\CompiledYamlFile-&amp;gt;content()
#3 /var/www/html/system/src/Grav/Common/Service/ConfigServiceProvider.php(30): Grav\Common\Config\Setup-&amp;gt;init()
#4 /var/www/html/vendor/pimple/pimple/src/Pimple/Container.php(118): Grav\Common\Service\ConfigServiceProvider-&amp;gt;Grav\Common\Service\{closure}(Object(Grav\Common\Grav))
#5 /var/www/html/system/src/Grav/Common/Grav.php(166): Pimple\Container-&amp;gt;offsetGet('setup')
#6 /var/www/html/system/src/Grav/Common/Grav.php(492): Grav\Common\Grav-&amp;gt;Grav\Common\{closure}()
#7 /var/ in &lt;b&gt;/var/www/html/system/src/Grav/Common/File/CompiledFile.php&lt;/b&gt; on line &lt;b&gt;81&lt;/b&gt;&lt;br /&gt;
-                    100% |******************************************************************************************************************************|  1167  0:00:00 ETA
written to stdout
</code></pre>

<p>I've tried adding a <code>securityContext</code> to the pod spec just to make sure nginx and php are run by the same user, but this prevents nginx from binding on 80/443. I've also tried exec-ing into the pod and I am able to modify files on the PV manually from both containers. How can I set up my pod spec so that Grav can write to the persistent volume claim mounted to <code>/var/www/html</code>?</p>

<hr>

<p><strong>UPDATE</strong> I don't have time to look further into it right now, but I suspect this is related to <code>php-fpm</code> spawning child processes as <code>www-data</code> user.</p>

littlebenlittle
<p>First of all, it might be easier to use the <a href="https://github.com/getgrav/docker-grav" rel="nofollow noreferrer">Docker provided by Grav</a>.</p>

<p>I tried to reproduce your problem with the following manifest:</p>

<pre><code>---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grav-data
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    run: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      run: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: web
    spec:
      volumes:
        - name: shared-files
          persistentVolumeClaim:
            claimName: grav-data
        - name: nginx-config-volume
          configMap:
            name: nginx-config
      containers:
        - name: app
          image: php:7.4-fpm
          imagePullPolicy: Always
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
        - name: nginx
          image: nginx:1.7
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
            - name: nginx-config-volume
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
        - name: tty      
          image: busybox:latest
          command: [ "/bin/sh", "-c", "sleep 6000" ]
          volumeMounts:
            - name: shared-files
              mountPath: /usr/share/nginx/html:ro
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {}
    http {
      error_log /dev/stdout info;
      server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name localhost;
        root /usr/share/www/html;
        index index.php;
        location / {
            try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
          include fastcgi_params;
          fastcgi_param REQUEST_METHOD $request_method;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_pass 127.0.0.1:9000;
        }
      }
    }
</code></pre>

<p>I'm using the Minikube StorageClass, so it provides me automatically with a PersistentVolume at /tmp/hostpath-provisioner/..., mounted at /usr/share/www/html:ro.</p>

<p>I've installed Grav with composer and ran:</p>

<pre><code>wget -O - localhost
Connecting to localhost (127.0.0.1:80)
wget: server returned error: HTTP/1.1 404 Not Found
</code></pre>

<p>Same with localhost/grav. It would be great to have some additional details to reproduce the problem (503).</p>

<p>I think your life will be so much easier if you deploy PHP-FPM and NGINX in separate pods with the service abstraction, considering you need to configure communication through the tcp port (127.0.0.1:9000) or unix socket (/var/run/php-fpm.sock). </p>

<p>You're probably not the first to install PHP-FPM and NGINX, there's a great <a href="https://www.digitalocean.com/community/tutorials/how-to-deploy-a-php-application-with-kubernetes-on-ubuntu-16-04" rel="nofollow noreferrer">tutorial on Digital Ocean</a> for this set-up.</p>
