配置Nginx在子目录部署Laravel API遇文件找不到问题求助
问题分析与解决方案
你的核心问题出在**alias指令与PHP路径参数的配合**以及try_files的规则上,以下是修正后的配置和关键说明:
修正后的Nginx配置
server { listen 80; server_name stackoverflow.com; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; charset utf-8; location ^~ /dev { alias /home/debian/www/stackoverflow/api/dev/public; # 优先匹配真实文件,不存在则转发到index.php try_files $uri $uri/ /dev/index.php$is_args$args; location = /dev/favicon.ico { access_log off; log_not_found off; } location = /dev/robots.txt { access_log off; log_not_found off; } error_page 404 /dev/index.php; error_log /home/debian/logs/nginx/error_log; access_log /home/debian/logs/nginx/access_log; location ~ \.php$ { # 必须用$request_filename获取alias映射后的真实文件路径 fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_index index.php; include fastcgi_params; } } location ~ /\.(?!well-known).* { deny all; } }
关键修改点说明
location ^~ /dev:添加^~前缀,确保这个location优先于正则匹配的规则,避免请求被意外拦截。try_files调整:把/dev/index.php?$query_string改为/dev/index.php$is_args$args,$is_args会在有查询参数时自动添加?,无参数时为空,比直接写?$query_string更严谨。SCRIPT_FILENAME参数:替换$fastcgi_script_name为$request_filename。因为用alias时,$fastcgi_script_name会保留/dev前缀(比如/dev/index.php),而真实文件路径是/home/debian/www/stackoverflow/api/dev/public/index.php,$request_filename会自动解析alias后的正确路径,让PHP-FPM能找到脚本文件,解决"Primary script unknown"错误。- 路由转发修复:修正后的
try_files会把所有非真实文件的请求(比如/dev/login)转发到index.php,由Laravel路由处理,而不是让Nginx尝试直接打开login文件,解决"open() ... failed"错误。
验证步骤
- 保存配置后,执行
nginx -t检查配置语法是否正确 - 重启Nginx:
systemctl restart nginx - 访问
http://stackoverflow.com/dev测试是否正常加载,再测试路由(比如/dev/login)是否能被Laravel正确处理
内容的提问来源于stack exchange,提问作者Dimitri
相关产品推荐
相关产品推荐

