核心是为每个站点配置独立PHP-FPM进程池,通过专属socket、用户隔离、open_basedir限制及Nginx精准指向实现资源与安全隔离。
在 Nginx 多域名环境下为不同 PHP 站点配置独立 PHP-FPM 池,核心目标是实现资源隔离、安全加固和故障互不影响。每个站点使用专属的 FPM 进程池(pool),意味着各自有独立的用户、内存限制、子进程数、日志路径和监听地址。
在 /etc/php/*/fpm/pool.d/ 目录下,为每个域名新建一个 .conf 文件,例如:
site1.com.conf 对应 site1.com
admin.site1.com.conf 对应后台子域site2.net.conf 对应第二个站点每个文件内容结构一致,仅参数按需差异化。以 site1.com.conf 为例:
[site1.com]user = site1group = site1listen = /run/php/php8.2-fpm-site1.socklisten.owner = www-datalisten.group = www-datalisten.mode = 0660
pm = dynamic pm.max_children = 20 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 5
slowlog = /var/log/php8.2-fpm-site1.slow.log access.log = /var/log/php8.2-fpm-site1.access.log access.format = "%R - %u %t "%m %r%Q%q" %s %f %{mili}d %{kilo}M %C%%"
php_admin_value[open_basedir] = /var/www/site1:/tmp php_admin_value[upload_tmp_dir] = /var/www/site1/tmp php_admin_value[session.save_path] = /var/www/site1/sessions
关键点:
listen 使用独立 Unix socket 路径,避免端口冲突且更安全user/group 建议为每个站点创建专用系统用户(如 adduser --home /var/www/site1 --shell /usr/sbin/nologin site1)open_basedir 强制限制脚本只能访问本目录及 tmp/session 子目录,防跨站读取每个站点的 Nginx 配置(如 /etc/nginx/sites-available/site1.com)必须与 FPM 池的 listen 地址严格匹配:
server {listen 80;server_name site1.com www.site1.com;root /var/www/site1;index index.php;location ~ .php$ {include snippets/fastcgi-php.conf;fastcgi_pass unix:/run/php/php8.2-fpm-site1.sock;← 必须与 pool 中 listen 一致fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;}}
注意:fastcgi_pass 的路径不能写错,也不能复用默认的 www.conf socket;否则所有站点将共用同一池,失去隔离意义。
确保系统层面权限闭环:
root:www-data,权限 644
www-data:www-data(因 listen.owner/group 已指定)www-data 组,才能访问 socket(检查 grep "worker_groups" /etc/nginx/nginx.conf)systemctl reload php8.2-fpm(加载新池),再 nginx -t && systemctl reload nginx
上线后快速验证是否生效:
sudo systemctl status php8.2-fpm → 观察输出中是否列出 site1.com、site2.net 等池名ls -l /run/php/php8.2-fpm-*.sock
info.php,访问后看 PHP Variables → $_SERVER['USER'] 是否等于池中定义的 user 值slowlog 是否有记录,确认日志分流有效这样配置后,一个站点的 PHP 内存溢出或死循环,不会拖垮其他站点,也杜绝了通过共享池越权访问他人文件的可能。