PHP-FPM + Nginx docker-compose stack没有重复的卷

k4ymrczo  于 12个月前  发布在  Nginx
关注(0)|答案(1)|浏览(93)

我在我的Vagrant + Ansible本地开发堆栈中有以下docker-compose(用于Ansible执行的master,用于VPS模拟的node-1):

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

我想用一个简单的phpinfo.php文件测试PHP-FPM,该文件从主机挂载到Nginx容器中的以下位置:/usr/share/nginx/html/phpinfo.php
运行这个文件,我得到了臭名昭著的空白页响应在我的浏览器。也许我的Nginx设置不好,所以我直接在PHP和Nginx容器上执行cgi-fcgi,但是/status/ping工作得很好:

$ 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

在下一步中,我用curl将一个简单的phpinfo文件复制到php容器中的/usr/share/nginx/html/phpinfo.php位置,令人惊讶的是,它返回了预期的HTML输出。因此,该问题可能与容器、卷和主机挂载文件之间的文件权限有关。
但是这种方法本身产生了一个新问题,因为现在我在phpnginx容器之间有两个不同版本的文件。一个是主机挂载的,另一个是由curl命令重写的,两者都在同一卷的路径下:

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();

?>

我需要在以下问题中得到一些建议:

  • 有没有一种方法可以在PHP和Nginx(或Apache)容器之间创建FastCGI连接,而不会将卷暴露给两个容器?
  • 如果只有在同一个容器中安装PHP和Nginx才有可能,那么在我看来,这就击败了“一个进程做一件事”的范例。我不认为这是一个解决方案。
  • 也许一个不那么痛苦的方法是使用一个多阶段构建Dockerfile?但是同样,PHP有它自己需要的系统包,所以这可能是行不通的。
  • 互联网上的很多资源都认为将应用程序放入带有git的容器是一种不好的做法,但似乎从主机挂载可能会产生另一个问题,因为如果在容器内修改文件,那么同一个挂载卷在另一个容器中可能会有不同的文件版本。
  • Dockerfile中的COPY命令可能是一个可行的解决方案,不会出现像我的情况(重复文件版本,如果一个容器修改文件)这样的主机安装问题。
    **如果你考虑将来使用CI/CD,请给予我一些建议,如何在多个容器之间正确处理Docker持久化数据。谢谢你!
    更新2020-07-30:

如果我绑定挂载同一个文件到php和nginx容器中(所以我放弃了命名卷),突然它就工作了:

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

然而,这一个没有:

- nginx:/usr/share/nginx

为什么命名卷会有不同的行为,为什么它适用于绑定挂载?

我检查了Laradock项目,它几乎在所有地方都使用绑定挂载。看起来我应该只在容器(比如数据库)内创建代码时才使用卷,对吗?如果我想将同一位置公开给多个容器,卷会发生什么?

w9apscun

w9apscun1#

构建过程:
1.使用包含php-fpm和apache的基础构建单个镜像(php-fpm-apache)
1.创建一个pod,其中包含两个容器,具有相同的图像,但在前台运行不同的命令。
1.(2.1)Apache的第一个容器(root用户)[root]。
1.(2.2)第二个容器与php-fpm(与continua用户在示例中)[非根]
参考示例:here

相关问题