多PHP-FPM容器(Nextcloud、Piwik)Nginx反向代理Docker部署问题
嘿,这个问题我之前帮朋友解决过,核心是别让Nginx直接挂载多个PHP-FPM容器的/var/www/html路径,咱们用官方镜像自带的配置就能完美搞定,不用改镜像本身!
核心思路
每个PHP-FPM容器(Nextcloud、Matomo/Piwik、你的自有应用)的/var/www/html是各自独立的文件系统,Nginx不需要直接访问这些文件——而是通过FastCGI协议把动态请求转发到对应的PHP-FPM容器,由FPM自己读取容器内的文件并处理。静态文件可以选择让Nginx直接处理(提升性能),但要给每个应用分配独立的挂载路径。
具体配置步骤
1. 调整docker-compose.yml
给每个PHP-FPM容器命名,用独立的卷存储应用数据/代码,Nginx只挂载自己的配置文件,不要挂载所有PHP应用的/var/www/html:
version: '3.8' services: nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d:/etc/nginx/conf.d # 可选:挂载每个应用的静态文件目录到Nginx的不同路径,用于直接处理静态资源 - nextcloud-data:/var/www/nextcloud - matomo-data:/var/www/matomo - ./custom-app/src:/var/www/custom-app depends_on: - nextcloud-fpm - matomo-fpm - custom-app-fpm nextcloud-fpm: image: nextcloud:fpm-alpine volumes: - nextcloud-data:/var/www/html # 专属卷存储Nextcloud的代码和数据 matomo-fpm: image: matomo:fpm-alpine # 注意:Piwik现在官方改名成Matomo了,镜像名是matomo volumes: - matomo-data:/var/www/html # 专属卷存储Matomo的代码和数据 custom-app-fpm: build: ./custom-app # 自有应用的Dockerfile,基于php:fpm-alpine即可 volumes: - ./custom-app/src:/var/www/html # 挂载你的自有应用代码到容器内的路径 volumes: nextcloud-data: matomo-data:
2. 配置Nginx的虚拟主机
给每个应用创建独立的Nginx配置文件,放在./nginx/conf.d目录下,核心是用fastcgi_pass指向对应的PHP-FPM容器,并设置正确的SCRIPT_FILENAME(指向PHP容器内的/var/www/html路径)。
Nextcloud的Nginx配置(nextcloud.conf)
server { listen 80; server_name nextcloud.yourdomain.com; # 静态资源直接由Nginx处理,提升性能 location ~ ^/(?:css|js|img|core|vendor|lib|templates)/ { root /var/www/nextcloud; # 对应Nginx容器内挂载的nextcloud-data卷路径 expires 1M; add_header Cache-Control "public, immutable"; } # 动态请求转发到Nextcloud FPM容器 location ~ \.php$ { fastcgi_pass nextcloud-fpm:9000; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; # 这里是PHP容器内的路径! include fastcgi_params; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param HTTPS on; } location / { try_files $uri $uri/ /index.php$request_uri; } }
Matomo(Piwik)的Nginx配置(matomo.conf)
server { listen 80; server_name matomo.yourdomain.com; # 静态资源直接处理 location ~ ^/(?:js|css|img|libs)/ { root /var/www/matomo; # Nginx容器内挂载的matomo-data卷路径 expires 1M; add_header Cache-Control "public, immutable"; } # 动态请求转发到Matomo FPM容器 location ~ \.php$ { fastcgi_pass matomo-fpm:9000; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; # PHP容器内的路径 include fastcgi_params; } location / { try_files $uri $uri/ =404; } }
自有应用的Nginx配置(custom-app.conf)
根据你的应用结构调整,核心逻辑一致:
server { listen 80; server_name app.yourdomain.com; # 静态资源处理(按需配置) location ~ ^/(?:css|js|images)/ { root /var/www/custom-app; expires 7d; } # 动态请求转发到自有应用FPM容器 location ~ \.php$ { fastcgi_pass custom-app-fpm:9000; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; include fastcgi_params; } location / { try_files $uri $uri/ /index.php$request_uri; } }
关键注意事项
- 绝对不要把多个PHP容器的
/var/www/html挂载到Nginx的同一个路径,这就是你之前冲突的根源。每个应用的文件系统是独立的,通过容器名区分即可。 - 官方的Nextcloud、Matomo FPM镜像默认都是以
/var/www/html为工作目录,所以SCRIPT_FILENAME必须指向这个容器内的路径,而不是Nginx里的挂载路径。 - Docker容器网络会自动解析容器名,所以Nginx配置里的
fastcgi_pass nextcloud-fpm:9000能直接访问到对应的FPM容器,不用担心端口冲突。 - 如果不需要Nginx直接处理静态文件,也可以完全不挂载应用的静态目录到Nginx,让FPM统一处理——只是性能会略差一点,适合小流量场景。
这样配置后,三个应用就能各自独立运行,Nginx通过域名区分请求,转发到对应的PHP-FPM容器,再也不会有路径冲突的问题啦!
内容的提问来源于stack exchange,提问作者user8184380
相关产品推荐
相关产品推荐

