thinkphp5 docker伪静态404的根本原因是nginx/apache未启用rewrite模块且public目录未设为web根目录,导致请求未进入index.php;需显式配置fastcgi_param path_info、正确设置root指向public、使用rewrite ^/(.*)$ /index.php/$1 last规则,并确保.htaccess在public下且allowoverride all生效。

ThinkPHP5 Docker容器里伪静态不生效,根本不是规则写错了
绝大多数人卡在「本地Apache能跑通,一进Docker就404」,真实原因是:Docker里用的Nginx或Apache镜像默认没开rewrite模块,且public目录没设为Web根目录——框架连入口文件都找不到,路由配置再对也没用。
Docker中Nginx镜像必须补全fastcgi_param PATH_INFO
ThinkPHP5依赖$_SERVER['PATH_INFO']解析URL,但官方nginx:alpine或nginx:latest镜像的fastcgi_params里默认不传这个变量,会导致URL pathinfo not supported错误。
- 在Nginx配置的
location ~ \.php$块内,必须显式加一行:fastcgi_param PATH_INFO $fastcgi_path_info; - 同时确保
fastcgi_split_path_info已启用,例如:fastcgi_split_path_info ^(.+\.php)(/.+)$; - 别用
try_files $uri $uri/ /index.php?$query_string;这种TP5不认的写法——它把参数塞进$_GET,而TP5默认不读s=参数 - 正确重写规则应为:
rewrite ^/(.*)$ /index.php/$1 last;(注意是/index.php/$1,不是/index.php?s=$1)
Apache镜像要确认mod_rewrite和AllowOverride都开了
用httpd:2.4这类官方镜像时,mod_rewrite默认不启用,.htaccess也直接被忽略。
- 构建镜像时需在
Dockerfile里加:RUN a2enmod rewrite(Debian系)或sed -i '/LoadModule rewrite_module/s/^#//g' /usr/local/apache2/conf/httpd.conf(Alpine系) -
.htaccess必须放在public/目录下(不是项目根目录),内容用标准TP5规则:RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] - Apache虚拟主机配置中,
<directory></directory>块内必须含AllowOverride All,否则.htaccess完全不加载 - 别漏掉
Options +FollowSymLinks,否则RewriteCond里的!-d/!-f判断会失效
Docker Compose里运行目录和路径映射必须对齐
伪静态失败的隐藏雷区:容器内DOCUMENT_ROOT指向/var/www/html,但你的代码实际在/var/www/html/public,导致Nginx转发到/index.php时404。
- 在
docker-compose.yml的nginx服务里,用volumes把宿主机./public映射到/var/www/html(不是整个项目) - 或者改Nginx配置的
root指令:设为root /var/www/html/public;,并把index.php路径调整为index index.php; - 如果用多应用结构(如
app1、app2),别指望子目录自动识别——得在Nginx里用if ($request_uri ~ "^/app1/(.*)$") { rewrite ^/app1/(.*)$ /index.php/app1/$1 last; }手动拆分
最常被跳过的动作:进容器执行curl -I http://localhost/index.php/index/index,先确认基础入口能通;再试curl -I http://localhost/index/index,看是否301或404——两步结果不同,说明问题一定出在重写层,而不是框架路由开关。TP5的url_route_on只是最后一道闸,前面服务器连请求都没转进来,开再多也没用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











