Docker双容器:无需挂载源码实现Caddy与PHP-FastCGI协同配置
理解Caddy与FastCGI的工作机制及配置优化
为什么NGINX容器无需挂载源码就能工作?
你的NGINX配置里,root /srv/app/public只是用来构造FastCGI请求参数,而非直接读取文件:
- 当请求PHP文件时,NGINX通过
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name把脚本路径传给PHP-FPM容器,实际的文件读取是由PHP-FPM完成的——它自身能访问到挂载的源码目录。 - 对于静态文件,配置里的
try_files $uri $uri/ /index.php?$query_string会把静态文件请求也转发到index.php(Symfony的前端控制器),所以NGINX不需要自己持有静态文件,最终还是由PHP-FPM处理这些请求。
Caddy默认配置的问题
Caddy的php_fastcgi指令默认会先检查本地文件是否存在,如果Caddy容器里没有挂载源码,它找不到对应的PHP文件或静态文件,就直接返回404,不会转发请求到PHP-FPM。同时,file_server指令也会尝试读取本地静态文件,这也是需要挂载源码的原因。
修改Caddy配置,无需挂载源码
要让Caddy像NGINX一样工作,需要调整两个核心逻辑:
- 跳过本地文件存在性检查,直接把所有请求转发给PHP-FPM
- 让Caddy正确构造传给PHP-FPM的脚本路径参数
基础配置(适配Symfony前端控制器逻辑)
localhost { php_fastcgi ${PHP_SERVICE_NAME}:9000 { # 强制指定SCRIPT_FILENAME,对应PHP-FPM容器内的源码路径 env SCRIPT_FILENAME /srv/app/public/index.php # 关闭Caddy的本地文件检查,按规则转发请求 try_files {path} {path}/ /index.php?{query} } # 移除file_server,静态文件由Symfony统一处理 }
灵活配置(支持直接访问PHP文件场景)
localhost { php_fastcgi ${PHP_SERVICE_NAME}:9000 { # 构造正确的SCRIPT_FILENAME,指向PHP-FPM容器内的实际路径 env SCRIPT_FILENAME /srv/app/public{uri} # 跳过本地文件检查,直接转发请求 try_files {path} {path}/ /index.php?{query} } }
关键说明
env SCRIPT_FILENAME:必须设置为PHP-FPM容器内的实际文件路径(和你PHP容器里的源码路径一致),这是PHP-FPM找到脚本的核心参数。try_files在php_fastcgi块内使用时,会跳过Caddy的本地文件存在性校验,直接按规则转发请求到PHP-FPM。- 移除
file_server,避免Caddy尝试读取本地静态文件,所有静态文件请求都由Symfony的前端控制器处理,和你NGINX配置的逻辑保持一致。
内容的提问来源于stack exchange,提问作者hoelska
相关产品推荐
相关产品推荐

