0
votes

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

1 Answers

0
votes

(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.