我在 Nginx 配置概念上遇到了一些问题。从nginx
SSL-terminator 反向代理开始,我使用一个docker-compose.yml
包含几个容器的设置,每个容器都提供一个虚拟服务。这些服务作为单个主机名下的子目录提供:
net --443--> nginx
| | `--- ContainerA "https://example.com/serviceA/"
| `----- ContainerB "https://example.com/serviceB/"
`------- ContainerC "https://example.com/serviceC/"
进程列表片段:
nginx:~$ ps fax
127285 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf -g daemon off;
127419 ? S 0:00 \_ nginx: worker process
127420 ? S 0:00 \_ nginx: worker process
127421 ? S 0:00 \_ nginx: worker process
ContainerA:~$ ps fax
127132 ? Ss 0:09 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
234053 ? S 8:27 \_ php-fpm: pool www
236952 ? S 8:12 \_ php-fpm: pool www
259123 ? S 6:42 \_ php-fpm: pool www
我认为,运行一个实例nginx
并php-fpm
在每个容器中使用可以提高效率。
我思考前提是php-fpm
容器不需要自己的nginx
进程;nginx
进程通过端口 9000 与每个容器通信(网络部分有效)。但在实践中,我遇到了麻烦,所以我需要验证我的前提是否合理:
这个基本架构的假设nginx
正确php-fpm
吗?或者,适当的nginx
/php-fpm
基础设施是否旨在php-fpm
直接协同使用(相同的主机和文件系统)或者多主机/多文件系统是否合理且有效?
(我最近联系了一些帮助,他们的第一反应是“你需要nginx
在每个容器中运行”,这与我的理解不符php-fpm
。)
(这里有很多问题都是针对具体nginx.conf
问题,而不是关于这个公认的高级架构的问题。)
答案1
这是一个很无力的答案,但我相信:
是的,这通常是正确的理念,但也有一些注意事项。php-fpm
用于处理.php
文件,但我认为不用于提供所有(非 php)文件。为此,前端进程nginx
需要查看所有文件,即使它不进行实际的 PHP 处理。
为了使用 docker 巧妙地实现这一点,容器中的文件php-fpm
需要与容器明确共享nginx
。在 docker 中执行此操作的首选方法是提供一个命名卷并将其用于两个容器。例如,一个docker-compose.yml
文件:
version: '2'
services:
serviceA:
image: ... # something served with php-fpm
volumes:
- tmpvolA:/path/to/serviceA
serviceB:
image: ... # something served with php-fpm
volumes:
- tmpvolB:/path/to/serviceB
nginx:
image: ...
volumes:
- tmpvolA:/var/www/serviceA
- tmpvolB:/var/www/serviceB
volumes:
tmpvolA:
tmpvolB:
(许多字段未包括在内...)最后列出的两个卷是docker所说的“命名卷”,并且出于某种原因而为空:启动脚本时它们应该是空的,并且将由其中一个容器填充。 (实际上,它可能由两者填充或都不填充,这取决于几个因素。)
这样做的一个副作用是坚持。
- 对于效率来说“这很好”,因为不需要不必要地重新创建它。
- “这很糟糕”,因为虚拟化服务的一个好处是您可以重新启动它并保证一切恢复正常。使用持久命名卷,您不会(自动)获得一切恢复正常,因为将使用上一个实例中使用的文件,而不是较低 fs 层中的简朴版本。
解决此“坏”问题的方法是手动刷新卷。这可以在关机时使用 完成docker-compose down -v
,根据帮助:
-v, --volumes Remove named volumes declared in the `volumes` section
of the Compose file and anonymous volumes
attached to containers.
docker volume rm <volume-id>
它也可以通过或手动完成docker volume prune
(删除所有当前未使用的卷,无论是临时的、命名的还是其他的)。