ThinkPHP容器化部署关键在四点对齐:public必须为Web根目录,runtime需可写且权限可控,Nginx须正确传递PATH_INFO和QUERY_STRING,环境变量须运行时注入;否则将导致路由404、敏感目录暴露、runtime写入失败及autoload加载异常。

ThinkPHP 容器化部署不靠堆配置,关键在四点对齐:public 目录作为 Web 根、runtime 目录可写且权限可控、Nginx 正确传递 PATH_INFO 和 QUERY_STRING、环境变量(如 TP_APP_ENV、TP_APP_DEBUG)运行时注入。
Web 根必须是 public 目录
ThinkPHP 6+ 默认采用入口分离结构,index.php 必须放在 public 下,且 Nginx 的 root 指向容器内 /var/www/html/public(或你设定的构建路径),不能指向项目根目录。否则会出现:
- 路由 404(
Route::rule()失效) - 敏感目录(如
app/、config/)被直接暴露 - runtime 写入失败(因入口文件路径错位导致自动加载异常)
多阶段 Dockerfile 推荐只保留 public/、runtime/、vendor/ 和必要配置,不打包源码到运行镜像。
runtime 权限要提前设宽松、挂载要拆开
报 file_put_contents(/runtime/): Permission denied,90% 是因为宿主机与容器用户 UID 不一致,或挂载方式不合理。硬改 chown 或依赖 entrypoint 补权限都不可靠。
立即学习“PHP免费学习笔记(深入)”;
- Dockerfile 中预创建并赋权:
RUN mkdir -p /var/www/runtime/{log,cache,route,view} && chmod -R 777 /var/www/runtime - docker-compose.yml 中单独挂载:
volumes: - ./runtime:/var/www/runtime:rw - 代码目录用只读挂载:
- ./public:/var/www/html/public:ro - 避免
-v ./app:/var/www这类整目录挂载
Nginx 必须传准 PATH_INFO 和 $query_string
默认配置下所有请求落到首页或 404,不是路由写错了,而是 $_SERVER['PATH_INFO'] 为空。核心配置两行缺一不可:
fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_param PATH_INFO $fastcgi_path_info;
同时确保:
-
root指向/var/www/html/public -
SCRIPT_FILENAME是$document_root$fastcgi_script_name(不是拼接变量或用$realpath_root) -
try_files $uri $uri/ /index.php?$query_string;——$query_string不能省,否则?s=api/user类参数丢失
依赖和环境必须构建时确定、运行时注入
Class 'think\App' not found 错误本质是 autoload.php 未生效,根源只有两个:vendor 没装上,或入口没引入 autoload。
- Dockerfile 分层 COPY:
COPY composer.json composer.lock .→RUN composer install --no-dev --optimize-autoloader→COPY . . - 确认
public/index.php开头有require __DIR__.'/../vendor/autoload.php'; - .env 不进镜像,通过
env_file或environment在 docker-compose.yml 中注入 - 禁用 dev 包:
--no-dev去掉 phpunit、faker 等,减体积、提安全



















