You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:53:00