linux部署thinkphp容器化核心是public根目录、runtime权限、nginx路由、环境变量四者对齐;缺一则导致404、class not found、permission denied或debug无法关闭。

Linux 上部署 ThinkPHP 容器化,核心不是“能跑就行”,而是让 public 入口、runtime 权限、Nginx 路由、环境变量四者对齐。错一个,就会 404、Class not found、Permission denied 或 debug 关不掉。
public 目录必须是 Web 根目录
ThinkPHP 6+ 默认采用入口分离结构,public 是唯一合法的 Web 根目录。常见错误是把整个项目挂载到 /var/www/html,结果 Nginx 直接暴露 app/、config/、.env 等敏感路径。
- Nginx 配置中
root必须指向容器内/var/www/html/public(不能是/var/www/html) - Dockerfile 构建时建议多阶段:第一阶段装依赖,第二阶段只复制
public/、vendor/、runtime/和必要配置,不打包 app/ 源码 - 挂载代码时用
-v $(pwd)/public:/var/www/html,而不是-v $(pwd):/var/www/html
runtime 目录权限要提前设好且单独挂载
容器启动后报 file_put_contents(/runtime/...): Permission denied,90% 是因为宿主机目录 UID 和容器内 www-data 用户不一致,或挂载方式不合理。
- 构建镜像时就创建并授权:
RUN mkdir -p /var/www/html/runtime/{log,cache,route,view} && chmod -R 777 /var/www/html/runtime - 运行容器时单独挂载 runtime:
-v $(pwd)/runtime:/var/www/html/runtime:rw,不要和代码混挂 - 若用 Docker Compose,在
volumes中显式声明,避免覆盖;Kubernetes 场景下推荐用emptyDir或 PVC,并加:z标签适配 SELinux - 每次重启前可清空缓存:
rm -rf runtime/{cache,route,session},防止模板编译冲突或路由失效
Nginx 必须正确传递 PATH_INFO 支持路由
默认 Nginx 配置下,Route::rule() 失效、所有请求都落到首页或 404,根本原因是 PATH_INFO 没传给 PHP-FPM。
-
location ~ \.php$块里必须包含两行:fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_param PATH_INFO $fastcgi_path_info; -
fastcgi_param SCRIPT_FILENAME必须写成$document_root$fastcgi_script_name,不能拼错或漏掉$document_root - 推荐用
try_files $uri $uri/ /index.php?$query_string;替代 rewrite,更稳定,也避免丢失 GET 参数
环境变量必须运行时注入,不能硬编码
.env 文件打进镜像等于泄露数据库密码;APP_DEBUG=true 打包进生产镜像会暴露敏感信息且无法灰度切换。
- 启动容器时用
-e TP_APP_ENV=production -e TP_APP_DEBUG=false注入 - 确保
config/app.php中读取逻辑为Env::get('TP_APP_ENV', 'production'),而非写死字符串 - 若平台限制环境变量前缀(如只允许
APP_),改用$_ENV['APP_ENV']并同步调整配置加载逻辑 - 验证是否生效:进容器执行
php think env:show(需安装 think-command)或打印Env::get('database.hostname')
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











