I’m new to kubernetes,
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.
Here’s the full yaml:
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: ["/bin/sh", "-c", "cp -r /app/. /var/www"]
- 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: "true"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: 100m
spec:
rules:
- host: testing.com
http:
paths:
- path: /
backend:
serviceName: operation-service
servicePort: 443
Here’s my working nginxconf
:
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;
}
After deploying, my app won’t load on the web. Turns out nginx log is returning:
[error] 19#19: *64 FastCGI sent in stderr: "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
I know how to setup the volume correctly in local docker, how do i set the shared volume permission in kubernetes correctly?
3
Answers
For anyone who is looking for answer, I manage to setup kubernetes for our production server with php-fpm and nginx.
It requires 2 image, 1 contains
php-fpm
and our code, the other one isnginx
image with our conf in it.Also we have to setup a shared volume between those 2 image to access. What I was missing was the
postStart
command to dochmod
andphp artisan optimize
to make sure I cleared the cacheFor future reference, please do
kubectl logs <pods-name>
andkubectl describe pods <pods-name>
to easily debug and see what happens in every podshere's the final working config, hope it helps someone in the future
You can use
init container
as described here to change permissions of mounted directories or you can set anfsGroup
to change the groupID that owns volume as described here.In your case I think it will be easier to set permissions by modifying your "copy" command:
adding a
chmod
command with appropriate parameters e.g:you can read the log and clearly mention permission denied which mean Nginx doesn’t have permission to access the file you might have to change the permission of directory or files so that Nginx can access it.
either you can change permission during the docker build or else run a prehook or set the command which will run with image at a time of deployment get updated.
something like :
or
i was trying to set up the WordPress same way along with php-fpm and using the Nginx container with php-fpm and faced same issue.
you find all the example files : https://github.com/harsh4870/Kubernetes-wordpress-php-fpm-nginx