Docker中多Nginx服务共用单个PHP-FPM实例实现方案问询
当然可行!这完全可以实现和你非Docker环境一样的架构——多个Nginx站点共用同一个PHP-FPM实例,本质上就是让所有Nginx容器都反向代理到同一个PHP服务,和传统环境里Nginx指向本地PHP-FPM是一个逻辑,只是Docker里用容器网络来连通。
我给你梳理下具体的实现步骤和配置要点:
核心逻辑
PHP-FPM本身是一个独立的TCP服务(默认监听9000端口),只要其他容器能通过网络访问到它,就能把PHP请求转发过去处理。所以关键就是让所有Nginx容器和PHP容器处于同一个Docker网络,并且在Nginx配置里把fastcgi_pass指向PHP容器的服务名(或者IP)。
调整Docker Compose配置
你原来的PHP服务保留,只需要新增多个Nginx服务,每个服务对应一个站点,同时确保所有服务都在同一个网络里(Docker Compose默认会给所有服务创建一个共享网络,也可以手动指定)。
比如修改后的docker-compose.yml:
version: '3.8' services: # 共用的PHP-FPM服务,保持你原来的配置 php: env_file: ".env" build: context: . dockerfile: php-fpm.dockerfile volumes: - "./server/www/:/var/www/:cached" # 挂载所有站点的代码目录,PHP需要读取这些文件 # 第一个站点的Nginx服务 nginx_site1: image: nginx:alpine volumes: # 挂载当前站点的代码目录(对应PHP容器里的/var/www/site1) - "./server/www/site1:/var/www/site1:cached" # 挂载当前站点的Nginx配置文件 - "./nginx/site1.conf:/etc/nginx/conf.d/default.conf:ro" ports: - "8080:80" # 第一个站点用8080端口对外访问 depends_on: - php # 确保PHP服务先启动 # 第二个站点的Nginx服务 nginx_site2: image: nginx:alpine volumes: - "./server/www/site2:/var/www/site2:cached" - "./nginx/site2.conf:/etc/nginx/conf.d/default.conf:ro" ports: - "8081:80" # 第二个站点用8081端口 depends_on: - php
配置Nginx站点
每个Nginx的配置文件里,关键是把fastcgi_pass指向PHP服务的名称(也就是Compose里的php服务名,Docker会自动解析成容器IP)。比如site1.conf的内容:
server { listen 80; server_name site1.local; # 可以自定义域名,本地测试需要改hosts root /var/www/site1; index index.php index.html; # 处理静态资源和路由 location / { try_files $uri $uri/ /index.php?$query_string; } # 转发PHP请求到共用的PHP-FPM服务 location ~ \.php$ { fastcgi_pass php:9000; # 这里用PHP服务名,不是localhost! fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
site2.conf的配置逻辑完全一样,只是root和server_name改成对应站点的内容即可。
几个关键注意事项
- 代码目录挂载:PHP容器必须挂载所有站点的代码目录(也就是你原来的
./server/www/:/var/www/),因为PHP-FPM需要读取代码文件来执行,Nginx容器挂载的只是各自站点的子目录,核心代码还是要让PHP能访问到。 - 网络连通性:如果没有用Compose的默认网络,一定要手动创建一个Docker网络,然后把PHP和所有Nginx服务都加入这个网络,否则Nginx找不到PHP服务。
- 资源限制:如果多个站点流量都比较大,建议给PHP容器设置资源限制(比如
cpus: "1.5"、memory: "1G"),避免单个PHP服务被压垮。 - 权限问题:确保PHP容器里的运行用户(通常是
www-data)对挂载的代码目录有读写权限,否则会出现PHP执行时的权限错误,可以在php-fpm.dockerfile里添加调整权限的命令,或者本地目录设置合适的权限。
这样配置完,你访问localhost:8080和localhost:8081就会分别对应两个站点,它们都会共用同一个PHP-FPM实例处理PHP请求,完全和你非Docker环境的架构一致。
内容的提问来源于stack exchange,提问作者SexyMF
相关产品推荐
相关产品推荐

