Docker环境下Nginx双PHP应用路由转发报文件未找到问题求助
问题:Docker环境下Nginx转发API到PHP应用时出现“文件未找到”错误
用户在Docker部署环境中,尝试通过Nginx将/api/(get-deals|get-deals/[^/]+|get-categories)这类API端点请求转发至对应index.php的PHP应用,其余请求转发至对应index-admin.php的PHP应用,但始终触发“文件未找到”错误。已确认/var/www/public目录下存在index.php和index-admin.php文件,以下是相关配置文件:
原Nginx配置
resolver 127.0.0.11; server { listen [::]:80; listen 80; root /var/www/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; index index.php index-admin.php; charset utf-8; location ~ /${MINIO_BUCKET}/(.*)/(.*)$ { set $dir $1; set $last_path_component $2; proxy_pass ${MINIO_URL}/${MINIO_BUCKET}/$dir/$last_path_component$is_args$args; proxy_pass_request_headers off; proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_hide_header Strict-Transport-Security; proxy_hide_header Content-Security-Policy; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; } location / { try_files $uri $uri/ /index-admin.php?$query_string; } location ~ ^/api/(get-deals|get-deals/[^/]+|get-categories) { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; error_page 404 /index-admin.php; location ~ /index\.php$ { fastcgi_pass ${PHP_CONTAINER}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /index-admin\.php$ { fastcgi_pass ${PHP_CONTAINER_ADMIN}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
原Dockerfile
FROM harbor.management.fib.dc/proxy_cache/nginx:stable-alpine WORKDIR /var/www/public/ RUN apk add --no-cache tzdata && echo "<?php" > index.php RUN apk add --no-cache tzdata && echo "<?php" > index-admin.php COPY conf/nginx.conf /etc/nginx/templates/default.conf.template COPY conf/config.template.json /etc/nginx/templates/config.json.template
问题排查与修复方案
1. 修复冲突的error_page配置
同时设置两个error_page 404会导致仅最后一个配置生效,删除冗余项:
# 保留一个符合业务逻辑的404跳转,其余删除 error_page 404 /index-admin.php;
2. 优化API路由的try_files逻辑
API请求对应的$uri(如/api/get-deals)本身不存在于磁盘,无需执行磁盘文件检查,直接重写至index.php即可:
location ~ ^/api/(get-deals|get-deals/[^/]+|get-categories) { rewrite ^ /index.php?$query_string last; }
3. 调整FastCGI location的匹配优先级
将index.php和index-admin.php的location改为精确匹配,避免正则匹配的优先级冲突:
location = /index.php { fastcgi_pass ${PHP_CONTAINER}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location = /index-admin.php { fastcgi_pass ${PHP_CONTAINER_ADMIN}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; }
4. 验证Docker容器内文件权限
确保Nginx进程(通常为nginx用户)拥有读取index.php和index-admin.php的权限,在Dockerfile中添加权限配置:
FROM harbor.management.fib.dc/proxy_cache/nginx:stable-alpine WORKDIR /var/www/public/ RUN apk add --no-cache tzdata && echo "<?php" > index.php RUN apk add --no-cache tzdata && echo "<?php" > index-admin.php # 添加权限设置 RUN chown -R nginx:nginx /var/www/public && chmod -R 755 /var/www/public COPY conf/nginx.conf /etc/nginx/templates/default.conf.template COPY conf/config.template.json /etc/nginx/templates/config.json.template
5. 调试FastCGI路径(可选)
若问题仍存在,可添加日志确认SCRIPT_FILENAME是否正确:
location = /index.php { fastcgi_pass ${PHP_CONTAINER}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 添加调试日志 access_log /var/log/nginx/api-access.log "$request_uri -> $realpath_root$fastcgi_script_name"; include fastcgi_params; }
查看/var/log/nginx/api-access.log确认路径是否为/var/www/public/index.php。
修改后的完整Nginx配置示例
resolver 127.0.0.11; server { listen [::]:80; listen 80; root /var/www/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; index index.php index-admin.php; charset utf-8; location ~ /${MINIO_BUCKET}/(.*)/(.*)$ { set $dir $1; set $last_path_component $2; proxy_pass ${MINIO_URL}/${MINIO_BUCKET}/$dir/$last_path_component$is_args$args; proxy_pass_request_headers off; proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_hide_header Strict-Transport-Security; proxy_hide_header Content-Security-Policy; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; } location / { try_files $uri $uri/ /index-admin.php?$query_string; } location ~ ^/api/(get-deals|get-deals/[^/]+|get-categories) { rewrite ^ /index.php?$query_string last; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index-admin.php; location = /index.php { fastcgi_pass ${PHP_CONTAINER}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location = /index-admin.php { fastcgi_pass ${PHP_CONTAINER_ADMIN}:${PHP_PORT}; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
内容的提问来源于stack exchange,提问作者Zheer Ardalan
相关产品推荐
相关产品推荐

