Nginx 多端口虚拟主机可共用同一 PHP-FPM FastCGI 池,只需统一 fastcgi_pass 指向相同地址(如 unix socket),并动态设置 SCRIPT_FILENAME;PHP-FPM 无感知端口差异,由自身进程管理并发。

在 Nginx 中,多个基于不同端口的虚拟主机(server 块)完全可以共用同一个 PHP-FPM FastCGI 池,无需为每个端口单独配置 upstream 或重复定义 fastcgi_pass。关键在于统一管理 FastCGI 连接参数,并确保各 server 块中正确引用该后端。
核心原理:FastCGI 是无状态协议,端口无关
Nginx 的 fastcgi_pass 指向的是一个 FastCGI 服务地址(如 127.0.0.1:9000 或 unix:/var/run/php/php8.1-fpm.sock),它不绑定到某个 server 的监听端口。只要多个 server 块都指向同一个 PHP-FPM 实例,它们就天然共享同一个 FastCGI 进程池。
配置示例:两个端口共用同一 sock 文件
以下是一个典型实战配置,监听 8080 和 8081 端口,均使用本地 Unix socket 连接同一 PHP-FPM 池:
# /etc/nginx/sites-available/shared-php
upstream php_backend {
server unix:/var/run/php/php8.1-fpm.sock;
}
server {
listen 8080;
server_name localhost;
root /var/www/site-a;
index index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
server {
listen 8081;
server_name localhost;
root /var/www/site-b;
index index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
✅ 这样配置后:
- 请求 http://localhost:8080/test.php 和 http://localhost:8081/test.php 都会通过同一个 php8.1-fpm.sock 提交到 PHP-FPM 进程池
- PHP-FPM 不感知 Nginx 的监听端口,只处理 CGI 请求并返回结果
- 所有并发请求由 PHP-FPM 自身的 pm.max_children、pm.start_servers 等参数统一调度
注意事项与常见问题
-
PHP-FPM 必须监听对应地址:确认
/etc/php/8.1/fpm/pool.d/www.conf中listen = /var/run/php/php8.1-fpm.sock且权限可读写(Nginx worker 用户需有访问 socket 的权限) -
SCRIPT_FILENAME 必须动态适配:每个 server 的
root不同,因此不能写死路径,必须用$document_root$fastcgi_script_name动态拼接,否则会导致 404 或 No input file specified -
避免混用 IP+端口和 Unix socket:若一个 server 用
127.0.0.1:9000,另一个用unix:/...,它们实际连接的是两个独立后端(除非你明确做了负载分发),不属于“共享池” -
日志与调试建议:开启 PHP-FPM 的
slowlog和access.log,配合 Nginx 的error_log debug可快速验证是否真走同一后端
进阶技巧:按端口区分 PHP 配置(可选)
虽然 FastCGI 池共享,但你可以通过 fastcgi_param 向 PHP 传递端口标识,用于运行时逻辑区分:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_X_SERVER_PORT $server_port;
}
这样 PHP 中可通过 $_SERVER['HTTP_X_SERVER_PORT'] 获取当前请求来自哪个端口,实现轻量级路由或环境判断。

















