【问题标题】:PHP-FPM + Nginx docker-compose stack without duplicate volumesPHP-FPM + Nginx docker-compose 堆栈没有重复卷
【发布时间】:2020-07-30 16:20:45
【问题描述】:

我的 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 Volumes 正确处理持久数据。谢谢!

2020 年 7 月 30 日更新:

如果我将相同的文件同时绑定到 php 和 nginx 容器中(所以我放弃了命名卷),它会突然起作用:

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

但是这个没有:

- nginx:/usr/share/nginx

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

我检查了Laradock 项目,它几乎在任何地方都使用绑定挂载。似乎我应该只在我的代码在容器(如数据库)内创建时才使用卷,对吗?如果我想将同一个位置暴露给多个容器,卷会发生什么情况?

【问题讨论】:

    标签: php docker nginx docker-compose laradock


    【解决方案1】:

    构建过程:

    使用包含 php-fpm 和 apache (php-fpm-apache) 的基础构建单个映像

    使用两个容器创建 pod,该容器具有相同的图像但在前台运行不同的命令

    第一个带有 apache 的容器(带有 root 用户)[root] 第二个带有 php-fpm 的容器(带有 continua 用户)[非 root]

    参考示例:here

    【讨论】:

      猜你喜欢
      • 2022-09-26
      • 2020-12-15
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      相关资源
      最近更新 更多