ThinkPHP8容器启动失败主因是runtime权限与.env配置错位:需在Dockerfile中预建runtime子目录并设777权限,挂载时确保宿主机目录非空;.env须置于项目根目录并通过env_file或ro卷注入,且基础镜像需启用putenv并配置variables_order=EGPCS。

ThinkPHP8 容器启动失败、日志写不进、.env 不生效——八成是目录权限或环境变量配置没对齐,不是代码问题。
runtime 目录权限必须显式放开,不能靠 chown
容器重启后 www-data 用户可能无法写入 runtime/log,报错 failed to open stream: Permission denied。这不是 SELinux 或挂载路径错了,而是 UID 不一致导致的静默拒绝。
- 在
Dockerfile里用RUN mkdir -p /var/www/html/runtime/{log,cache,route,view} && chmod -R 777 /var/www/html/runtime,别用chown - 挂载时用
volumes: - ./runtime:/var/www/html/runtime:rw,确保宿主机目录存在且非空(首次启动前可手动mkdir -p runtime/log) - 如果用 Alpine 镜像,
www-data用户默认不存在,得先addgroup -g 82 -f www && adduser -S www -u 82再设权限
.env 文件必须放在项目根目录,且不能打进镜像
ThinkPHP 默认只读取项目根目录下的 .env,而你挂载的是 public/ 到 /var/www/html,容器内根目录其实是 /var/www/html/.. ——但这个路径往往不可写,也未挂载。
- 在
Dockerfile中保留项目根目录结构,比如设WORKDIR /var/www,再把代码 COPY 到/var/www/html,然后把.env放在/var/www/.env - 运行时用
docker run -v $(pwd)/.env:/var/www/.env:ro或docker-compose.yml中的env_file: [".env"]注入 - 验证是否加载成功:进容器执行
php think env:show(需装think-command),或直接php -r "var_dump(\think\Env::get('app.debug'));"
环境变量要穿透到 PHP 运行时,不能只靠 $_ENV
有些镜像(尤其是 Alpine)默认禁用 putenv(),导致 .env 里的 DB_HOST=${DB_HOST} 语法失效,$_ENV 为空,但 getenv('DB_HOST') 又能取到——这种不一致会让数据库连不上。
立即学习“PHP免费学习笔记(深入)”;
- 确保基础镜像启用
putenv:检查php.ini是否有disable_functions = putenv,若有则删掉或覆盖 - 在
Dockerfile中加RUN echo "variables_order = \"EGPCS\"" >> /usr/local/etc/php/php.ini,保证环境变量优先级正确 - 若用
docker run -e DB_HOST=172.18.0.2传参,.env中必须写成DB_HOST=${DB_HOST},且确认 PHP 版本 ≥ 7.4(低版本不支持嵌套变量展开)
最常被忽略的是:挂载 runtime 后没清空旧缓存,容器重启时模板编译文件残留,导致路由解析异常或类找不到;还有就是 .env 被 git 提交又没加 .dockerignore,一构建就泄露密钥。



















