I am building an php image containing a composer magento installation. The content is stored in /var/www/html of the image. Now I have a Php-Image and some deployment files. But the contents of the images /var/www/html folder are not shown in any created POD. First I was thinking, that I have to create a volume in the PHP image, mapping to the /var/www/html path. But that did not help (but it seems logical to me).
Maybe there is a problem with the persistent volume claim? I read, that I have to create a volume in the php and nginx container with the same /var/www/html path, so that php content can be executed by nginx, so I did that. But now I am not sure if that is really the way to do it and it interferes with the PVC.
PHP Docker-Image
# image
FROM php:7.1-fpm
# envs
ENV INSTALL_DIR /var/www/html
# install composer
RUN curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer
# install libraries
... shortended ...
# set memory limits
RUN echo "memory_limit=2048M" > /usr/local/etc/php/conf.d/memory-limit.ini
# clean apt-get
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# www-data should own /var/www
RUN chown -R www-data:www-data /var/www
# switch user to www-data
USER www-data
# copy sources with proper user
COPY --chown=www-data ./magento2/composer $INSTALL_DIR
# set working dir
WORKDIR $INSTALL_DIR
RUN composer install
# chmod directories
RUN chmod u+x bin/magento
# switch back
USER root
VOLUME $INSTALL_DIR
Deployments 1. Persistent Volume Claim
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume-magento
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
2. PHP Deployment (using the build image with the web application)
apiVersion: apps/v1
kind: Deployment
metadata:
name: php
labels:
app: php
spec:
replicas: 1
selector:
matchLabels:
app: php
template:
metadata:
labels:
app: php
tier: frontend
spec:
containers:
- name: php-mage
image: php-mage:latest
imagePullPolicy: Never
volumeMounts:
- name: magento2-persistent-storage
readOnly: false
mountPath: /var/www/html
volumes:
- name: magento2-persistent-storage
persistentVolumeClaim:
claimName: magento2-volumeclaim
3. Nginx Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
tier: frontend
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
- containerPort: 443
volumeMounts:
- name: magento2-persistent-storage
readOnly: false
mountPath: /var/www/html
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: nginx-site-config-volume
mountPath: /etc/nginx/sites-enabled/default.conf
subPath: default.conf
- name: fastcgi-snippet-volume
mountPath: /etc/nginx/snippets/fastcgi-php.conf
subPath: fastcgi-php.conf
volumes:
- name: magento2-persistent-storage
persistentVolumeClaim:
claimName: magento2-volumeclaim
- name: nginx-config-volume
configMap:
name: nginx-config
- name: nginx-site-config-volume
configMap:
name: nginx-site-config
- name: fastcgi-snippet-volume
configMap:
name: nginx-fastcgi-config
EDIT: I realized, when I am using subPath in the php-deployment.yaml like that:
volumeMounts:
- name: magento2-persistent-storage
readOnly: false
mountPath: /var/www
subPath: html
My content is available in the PHP Pod. But I can't add the same logic to the nginx deployment, because it overwrites the contents and the folder is empty again.
Now, a step further, but still the question how to do this correctly. Do I have to share a mountPath between nginx and php?
(1) You do have live data baked into your image but override it by mounting a volume to the same path. If data is not to be changed during runtime, don't mount a volume. If it is, use another path and copy live data over on initialization of your Pod.
(2) You have a single PVC with ReadWriteOnce
, but your PHP deployment is of kind Deployment
that can be scaled (you initialize it with 1 replica). As soon as you try to scale it up all its Pods other than the first one will fail because they won't be able to access the same claim with write access.
(3) You have a second deployment and try to reuse the same ReadWriteOnce
volume. Same problem as (2) will occur.
Circumvent all of this by spawning your Pods with their own individual PVCs (you can have them built from volumeClaimTemplates
) automatically that only belong to a single Pod. Properly initialize each Pod by setting its container data "live"; copy it to the mount where it can be changed during runtime. If you need consistency of files between Pods in different deployments, spin up an in-cluster NFS server to provide ReadWriteMany
volumes.