2

I have the following docker-compose in my Vagrant + Ansible local development stack (master for Ansible execution, node-1 for VPS simulation):

version: "3.8"

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

volumes:
  nginx:
    driver: local

services:

### PHP ########################################################################
  php:
    image: php:7.4.8-fpm-buster
    expose:
      - "9000"
    networks:
      - backend
    volumes:
      - /usr/src/app/docker/php/php.ini:/usr/local/etc/php/php.ini:ro
      - /usr/src/app/docker/php/zzz.ini:/usr/local/etc/php/conf.d/zzz.ini:ro
      - /usr/src/app/docker/php/zzz.conf:/usr/local/etc/php-fpm.d/zzz.conf:ro
      - nginx:/usr/share/nginx

### Nginx ######################################################################
  nginx:
    image: nginx:1.19.1
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - php
    networks:
      - frontend
      - backend
    environment:
      - NGINX_HOST=app.test
      - NGINX_PORT=80
    volumes:
      - /usr/src/app/docker/nginx/templates:/etc/nginx/templates
      - /usr/src/app/docker/src/phpinfo.php:/usr/share/nginx/html/phpinfo.php
      - nginx:/usr/share/nginx

I want to test PHP-FPM with a simple phpinfo.php file, which is mounted from the host to the following location in the Nginx container: /usr/share/nginx/html/phpinfo.php

Running this file I'm getting the infamous blank page response in my browser. Maybe I have bad Nginx settings, so I executing cgi-fcgi directly on both PHP and Nginx container also, but /status and /ping works just fine:

$ ansible node-1 -b -a "docker exec -it app_php_1 /bin/bash -c 'SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping QUERY_STRING=full REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000'"
node-1 | CHANGED | rc=0 >>
X-Powered-By: PHP/7.4.8
Content-type: text/plain;charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0

pong
$ ansible node-1 -b -a "docker exec -it app_nginx_1 /bin/bash -c 'SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping QUERY_STRING=full REQUEST_METHOD=GET cgi-fcgi -bind -connect php:9000'"
node-1 | CHANGED | rc=0 >>
X-Powered-By: PHP/7.4.8
Content-type: text/plain;charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0

pong

In the next step, I copy with curl a simple phpinfo file into /usr/share/nginx/html/phpinfo.php location in php container and surprise, it's returning the expected HTML output. So the issue is probably related to file permissions between the containers, volumes and host mounted files.

But this approach creates a new problem on it's own, because now I have two different versions of a file between the php and nginx container. One is host mounted, the another one is rewritten by the curl command, both under the path of the same volume:

vagrant@master:~$ ansible node-1 -b -a "docker exec -it app_php_1 cat /usr/share/nginx/html/phpinfo.php"
node-1 | CHANGED | rc=0 >>
<?php

phpinfo();
vagrant@master:~$ ansible node-1 -b -a "docker exec -it app_nginx_1 'cat /usr/share/nginx/html/phpinfo.php"
node-1 | CHANGED | rc=0 >>
<?php

phpinfo();

?>

I need some advice in the following questions:

  • Is there a way to create FastCGI connection between a PHP and Nginx (or Apache) container without exposing a volume to both containers?
  • If it's only possible if I install both PHP and Nginx in the same container, in my mind this is defeats the "one process for one thing" paradigm. I don't consider this a solution.
  • Maybe a less painful approach would be using a multi-stage build Dockerfile? But again, PHP have it's needed system packages on it's own, so this is probably not gonna work...
  • Lot of resources on the internet considering getting your app into containers with git as a bad practice, but seems like mounting from the host can create another problem, because if a file modified inside a container, the same mounted volume can have a different file version in another container.
  • A COPY command in a Dockerfile can be a viable solution to not have host mounted problems like in my case (duplicate file versions, if one container modifying the file)?

Please give me some advice how to properly handle persisting data with Docker Volumes between multiple containers, if you consider using CI/CD on the future also. Thank You!

Update 2020-07-30:

If I bind mounting the same file both into php and nginx containers (so I abandone the named volumes), suddanly it works:

- /usr/src/app/docker/src/phpinfo.php:/usr/share/nginx/html/phpinfo.php

However this one doesn't:

- nginx:/usr/share/nginx

Why is this different behavior with named volumes and why it works with bind mounts?

I examined the Laradock project and it also uses bind mounts almost everywhere. Seems like I should only use volumes when my code created inside the containers (like a database), am I right? What's happening with volumes if I want to expose the same location to multiple containers?

Lanti
  • 2,299
  • 2
  • 36
  • 69

1 Answers1

0

build process:

Build a single image using the base containing php-fpm and apache (php-fpm-apache)

create pod with two containers with the same image but different command running in the foreground

1st container with apache (with root user)[root] 2nd container with php-fpm (with continua user)[non-root]

Ref example: here

WSMathias9
  • 669
  • 8
  • 15