public目录必须是Web服务器根目录,否则ThinkPHP6.0容器启动后路由全崩、静态资源404、ROOT变空字符串;nginx root须指向/var/www/html,挂载点仅限./public,且需正确配置PATH_INFO、runtime权限、.env位置及PHP-FPM与Nginx用户UID一致性。

public 目录必须是 Web 服务器根目录,否则 ThinkPHP6.0 容器启动后路由全崩、静态资源 404、<strong>ROOT</strong> 变空字符串——这不是配置问题,是容器里 Nginx 或 Apache 根本没指向对地方。
nginx root 必须指向 /var/www/html,且挂载点只能是 ./public
常见错误是用 docker run -v $(pwd):/var/www/html 把整个项目根目录挂进去,结果 app/、config/、composer.json 全暴露在 Web 下,既不安全又导致 index.php 找不到框架核心。
- 正确挂载方式:Nginx 容器只挂
./public:/var/www/html,不能挂./:/var/www/html - 验证方法:进 Nginx 容器执行
ls -l /var/www/html,应只看到index.php、static/、router.php,绝不能出现app/或runtime/ - Docker Compose 中写法示例:
volumes: - ./public:/var/www/html
- 如果用了宝塔等宿主机 Nginx,需反向代理到 PHP-FPM 容器的
127.0.0.1:9000(或自定义端口),而非走本地 PHP
runtime 目录权限不对会导致静默失败
file_put_contents(/var/www/runtime/log/app.log) 权限拒绝不会报错到页面,但日志不写、缓存不生成、队列起不来——访问空白页时先查容器内 php-error.log,大概率是这行。
- 构建镜像时就创建并设宽松权限:
RUN mkdir -p /var/www/runtime/{log,cache,route,view} && chmod -R 777 /var/www/runtime - 运行时挂载必须独立:
-v $(pwd)/runtime:/var/www/runtime:rw,不能和代码混挂 - SELinux 主机(如 Alibaba Cloud Linux 3)要加
:Z后缀:-v $(pwd)/runtime:/var/www/runtime:Z - 多实例部署时,每个服务的
runtime挂载路径必须唯一,例如./runtime-prod和./runtime-staging
PATH_INFO 为空导致所有路由 fallback 到首页
Nginx 默认不拆分 PATH_INFO,$_SERVER['PATH_INFO'] 始终为空,ThinkPHP 的 Route::rule() 全部失效,/user/list 自动跳首页或 404。
立即学习“PHP免费学习笔记(深入)”;
- 必须在
location ~ \.php$块中显式配置:fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info;
- 确认
fastcgi_param SCRIPT_FILENAME是绝对路径,例如/var/www/html/index.php,不是$document_root/index.php(后者在挂载结构下容易出错) - PHP-FPM 容器内监听地址要和 Nginx 的
fastcgi_pass对齐,常见组合是fastcgi_pass php-fpm:9000+listen = 9000(注意不是127.0.0.1:9000,容器间通信走 Unix socket 或服务名更稳)
.env 文件挂载位置错了就读不到环境变量
APP_DEBUG=false 却还在页面输出错误,或数据库连不上,大概率是 .env 没加载成功——ThinkPHP 从项目根目录读,不是从 public/ 下读。
-
.env必须放在宿主机项目根目录(如$(pwd)/.env),再挂载到容器根目录:-v $(pwd)/.env:/var/www/.env - 不能挂成
-v $(pwd)/.env:/var/www/html/.env,因为public是子目录,框架启动时getcwd()是/var/www/html,向上找一层才是项目根 - 验证是否生效:
docker exec -it your-php-container php -r "var_dump(\think\Env::get('app.debug'));" - 生产环境别用
COPY .env打进镜像,敏感信息会留在镜像层,用environment:或--env-file注入更安全
实际部署中最容易被忽略的是:PHP-FPM 和 Nginx 容器之间的用户 UID 是否一致,以及 runtime 目录在宿主机上的属主是否与容器内 www-data 用户 UID 匹配——不同基础镜像的 www-data UID 可能不同,硬改 chown 在容器重启后失效,用 chmod -R 777 或 :Z 更可靠。



















