<p>I'm new to kubernetes,</p>
<p>Currently i'm triyng to deploy laravel app on kuberetes. I have setup 1 deployment yaml containing 2 containers (nginx and php-fpm) and a shared volume.</p>
<p>Here's the full yaml:</p>
<pre><code>
apiVersion: v1
kind: Service
metadata:
  name: operation-service
  labels:
    app: operation-service
spec:
  type: NodePort
  selector:
    app: operation
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  - port: 9000
    targetPort: 9000
    protocol: TCP
    name: fastcgi

---
# Create a pod containing the PHP-FPM application (my-php-app)
# and nginx, each mounting the `shared-files` volume to their
# respective /var/www/ directories.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: operation
spec:
  selector:
    matchLabels:
      app: operation
  replicas: 1
  template:
    metadata:
      labels:
        app: operation
    spec:
      volumes:
        # Create the shared files volume to be used in both pods
        - name: shared-files
          emptyDir: {}

        # Secret containing
        - name: secret-volume
          secret:
            secretName: nginxsecret

        # Add the ConfigMap we declared for the conf.d in nginx
        - name: configmap-volume
          configMap:
            name: nginxconfigmap

      containers:
        # Our PHP-FPM application
        - image: asia.gcr.io/operations
          name: app
          volumeMounts:
            - name: shared-files
              mountPath: /var/www
          ports:
            - containerPort: 9000
          lifecycle:
            postStart:
              exec:
                command: [&quot;/bin/sh&quot;, &quot;-c&quot;, &quot;cp -r /app/. /var/www&quot;]

        - image: nginx:latest
          name: nginx
          ports:
            - containerPort: 443
            - containerPort: 80
          volumeMounts:
            - name: shared-files
              mountPath: /var/www
            - mountPath: /etc/nginx/ssl
              name: secret-volume
            - mountPath: /etc/nginx/conf.d
              name: configmap-volume

---

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: &quot;true&quot;
    nginx.ingress.kubernetes.io/from-to-www-redirect: &quot;true&quot;
    nginx.ingress.kubernetes.io/proxy-body-size: 100m
spec:
  rules:
  - host: testing.com
    http:
      paths:
      - path: /
        backend:
          serviceName: operation-service
          servicePort: 443
</code></pre>
<p>Here's my working <code>nginxconf</code>:</p>
<pre><code>server {
    listen 80;
    listen [::]:80;

    # For https
    listen 443 ssl;
    listen [::]:443 ssl ipv6only=on;
    ssl_certificate /etc/nginx/ssl/tls.crt;
    ssl_certificate_key /etc/nginx/ssl/tls.key;

    server_name testing.com;
    root /var/www/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }


    error_log /var/log/nginx/laravel_error.log;
    access_log /var/log/nginx/laravel_access.log;
}

</code></pre>
<p>After deploying, my app won't load on the web. Turns out nginx log is returning:</p>
<pre><code>[error] 19#19: *64 FastCGI sent in stderr: &quot;PHP message: PHP Fatal error:  Uncaught ErrorException: file_put_contents(/app/storage/framework/views/ba2564046cc89e436fb993df6f661f314e4d2efb.php): failed to open stream: Permission denied in /var/www/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:185
</code></pre>
<p>I know how to setup the volume correctly in local docker, how do i set the shared volume permission in kubernetes correctly?</p>

Robert Tirta
<p>For anyone who is looking for answer, I manage to setup kubernetes for our production server with php-fpm and nginx.</p>
<p>It requires 2 image, 1 contains <code>php-fpm</code> and our code, the other one is <code>nginx</code> image with our conf in it.</p>
<p>Also we have to setup a shared volume between those 2 image to access. What I was missing was the <code>postStart</code> command to do <code>chmod</code> and <code>php artisan optimize</code> to make sure I cleared the cache</p>
<p>For future reference, please do <code>kubectl logs &lt;pods-name&gt;</code> and <code>kubectl describe pods &lt;pods-name&gt;</code> to easily debug and see what happens in every pods</p>
<p>here's the final working config, hope it helps someone in the future</p>
<pre><code>
apiVersion: v1
kind: Service
metadata:
  name: operation-service
  labels:
    app: operation-service
spec:
  type: NodePort
  selector:
    app: operation
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
---
# Create a pod containing the PHP-FPM application (my-php-app)
# and nginx, each mounting the `shared-files` volume to their
# respective /var/www/ directories.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: operation
spec:
  selector:
    matchLabels:
      app: operation
  replicas: {{ .Values.replicaCount }}
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: operation
    spec:
      volumes:
        # Create the shared files volume to be used in both pods
        - name: shared-files
          emptyDir: {}
      securityContext:
        fsGroup: 82
      containers:
        # Our PHP-FPM application
        - image: asia.gcr.io/3/operations:{{ .Values.version }}
          name: app
          envFrom:
          - configMapRef:
              name: prod
          - secretRef:
              name: prod
          volumeMounts:
            - name: shared-files
              mountPath: /var/www
          # Important! After this container has started, the PHP files
          # in our Docker image aren't in the shared volume. We need to
          # get them into the shared volume. If we tried to write directly
          # to this volume from our Docker image the files wouldn't appear
          # in the nginx container.
          #
          # So, after the container has started, copy the PHP files from this
          # container's local filesystem (/app -- added via the Docker image)
          # to the shared volume, which is mounted at /var/www.
          ports:
            - containerPort: 9000
              name: fastcgi
          lifecycle:
            postStart:
              exec:
                command:
                  - &quot;/bin/sh&quot;
                  - &quot;-c&quot;
                  - &gt;
                    cp -r /app/. /var/www &amp;&amp;
                    cd /var/www &amp;&amp;
                    php artisan optimize &amp;&amp;
                    php artisan migrate --force &amp;&amp;
                    chgrp -R www-data /var/www/* &amp;&amp;
                    chmod -R 775 /var/www/*

        # Our nginx container, which uses the configuration declared above,
        # along with the files shared with the PHP-FPM app.
        - image: asia.gcr.io/3/nginx:1.0
          name: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - name: shared-files
              mountPath: /var/www


# We don't need this anymore as we're not using fastcgi straightaway
# ---

# apiVersion: v1
# kind: ConfigMap
# metadata:
#   name: ingress-cm
# data:
#   SCRIPT_FILENAME: &quot;/var/www/public/index.php$is_args$args&quot;

---

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: operation-ingress
  labels:
    app: operation-ingress
  annotations:
    kubernetes.io/ingress.class: &quot;nginx&quot;
    nginx.ingress.kubernetes.io/ssl-redirect: &quot;true&quot;
    nginx.ingress.kubernetes.io/force-ssl-redirect: &quot;true&quot;
    nginx.ingress.kubernetes.io/from-to-www-redirect: &quot;true&quot;
    nginx.ingress.kubernetes.io/proxy-body-size: &quot;0&quot;
    cert-manager.io/cluster-issuer: letsencrypt-prod

spec:
  tls:
    - hosts:
        - myservice.com.au
      secretName: kubernetes-tls
  rules:
  - host: myservice.com.au
    http:
      paths:
      - backend:
          serviceName: operation-service
          servicePort: 80
</code></pre>
