Nginx子路径路由异常:Docker部署Laravel多版本项目问题
问题分析与解决方案
你的核心问题是Nginx没有正确将/api/v2开头的请求转发到php84容器,主要是匹配优先级和路径处理逻辑出错,以下是具体排查和修复方案:
常见配置错误点
1. 匹配优先级被覆盖
如果你的/api/v2 location配置在/之后,且没有强制前缀匹配的修饰符,Nginx可能会优先走/的处理逻辑(尽管前缀匹配是最长优先,但/的try_files可能直接拦截请求)。
2. Alias与FastCGI的路径冲突
用alias指向v2的public目录时,Nginx会把$fastcgi_script_name(包含/api/v2前缀)拼接到alias路径后,生成不存在的文件路径(比如/var/www/html/v2/public/api/v2/index.php),导致直接返回404,根本不会转发到php84。
正确的Nginx配置示例
替换你的default.conf为以下内容:
server { listen 80; server_name localhost; # 优先处理/api/v2开头的请求 location ^~ /api/v2 { # 重写URL,去掉/api/v2前缀,让Laravel处理真实路由 rewrite ^/api/v2/(.*)$ /$1 break; # 转发到php84容器 fastcgi_pass php84:9000; # 指定v2项目的入口文件 fastcgi_param SCRIPT_FILENAME /var/www/html/v2/public/index.php; # 传递必要的FastCGI参数 fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT /var/www/html/v2/public; include fastcgi_params; } # 处理所有其他请求到v1项目 location / { root /var/www/html/v1/public; index index.php index.html; try_files $uri $uri/ /index.php?$query_string; fastcgi_pass php82:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 禁止直接访问php文件,避免安全风险 location ~ \.php$ { return 404; } }
配置说明
^~ /api/v2:强制Nginx优先匹配该前缀,确保/api/v2请求不会被后续的/规则拦截。rewrite ^/api/v2/(.*)$ /$1 break:移除/api/v2前缀,让Laravel能解析自身的路由(比如/api/v2/user会被转成/user传递给v2项目)。- 明确指定
SCRIPT_FILENAME:避免路径拼接错误,直接指向v2的入口文件。 - 完整传递FastCGI参数:确保Laravel能正确获取请求的URI、方法等信息。
验证步骤
- 重启Nginx容器:
docker-compose restart nginx - 访问
/api/v2/xxx测试,查看php84日志:docker logs php84,确认请求是否到达。 - 若仍有问题,查看Nginx日志:
docker logs nginx,排查是否有路径或连接错误。
额外检查项
- 确认php84容器内的v2项目路径确实是
/var/www/html/v2,且public目录存在。 - 确保docker-compose.yml中php84的服务名称是
php84,Nginx容器能通过该名称访问到php84(默认Docker网络内服务互通)。
内容的提问来源于stack exchange,提问作者celyes
相关产品推荐
相关产品推荐

