TP6容器化最稳妥但需锁定PHP 7.3+,TP8性能更好但强制PHP≥8.0,TP3.2/TP5.x容器化风险高且兼容性差。

TP6 容器化部署最稳妥,但必须锁死 PHP 7.3+ 版本
ThinkPHP 6.x 是目前容器化落地最成熟的版本——它从设计上就面向现代部署场景,原生支持 PSR-15 中间件、Composer 依赖隔离、环境变量驱动配置,和 Docker 的契合度高。但关键陷阱在于:TP6.1.2 起才明确支持 PHP 8.2,而早期 TP6.0.x 在 PHP 8.0+ 下会因 ReflectionParameter::isArray() 等废弃方法直接报 Fatal error,连容器启动都失败。
- 镜像基础必须选
php:7.4-apache或php:8.1-fpm(别用latest) -
Dockerfile中务必显式声明ENV APP_ENV=production,否则 TP6 的调试模式可能暴露路径或触发未预期的异常捕获逻辑 - 挂载代码时避免覆盖
runtime/目录,否则容器重启后日志/缓存全丢,且chmod -R 777 runtime在 Alpine 镜像里容易因用户 UID 不一致失效
TP8 容器化性能更好,但 PHP 7.x 镜像完全不可用
TP8.1 强制要求 PHP ≥ 8.0,底层已重写反射逻辑,用 $param->getType()->getName() 替代旧式判断,彻底避开 PHP 8 的弃用警告。实测在同等 Nginx + PHP-FPM 容器配置下,TP8 的路由匹配耗时比 TP6 低约 12%(基于 ab -n 10000 -c 200 测试),但代价是零兼容性妥协:只要镜像里是 PHP 7.4,composer install 阶段就会因联合类型语法(string|int)直接报 Parse error,根本跑不到容器启动环节。
- 必须使用
php:8.0-cli或更高版本构建镜像,Alpine 用户注意选php:8.2-alpine3.18(3.17 及更早版 OpenSSL 版本过低,会卡在openssl_pkey_new()报错) - TP8 的容器启动时会校验
app.provider中服务类的构造函数类型声明,若某服务依赖DateTimeInterface但容器注入的是DateTime实例,运行时抛TypeError,不是 warning - 软删除字段默认行为变更(TP8 改为严格检查
delete_time是否为null),若数据库该字段存了0000-00-00 00:00:00,查不到数据且无提示
TP3.2 和 TP5.x 容器化等于“手动排雷”
TP3.2 在 PHP 7.0+ 容器里根本起不来——mysql_connect() 被移除、String 类冲突、E_DEPRECATED 错误升级为致命错误;TP5.1 虽能跑,但 PHP 8.0+ 下 count(): Parameter must be an array or an object 这类错误遍布模型关联、分页、验证器等核心路径,属于“页面能打开,点一下就 500”的状态。
- TP3.2 唯一可行方案是固定用
php:5.6-apache镜像,但该镜像已停止安全更新,Docker Hub 上的官方 tag 实际是 2022 年最后构建,存在已知 OpenSSL 漏洞 - TP5.1 若强行上 PHP 7.4,需全局替换所有
count($var)为is_array($var) || $var instanceof Countable ? count($var) : 0,涉及 vendor/thinkphp/src/ 下至少 17 个文件 - TP5 的路由缓存机制与 Docker 卷挂载不兼容:
route.php改动后,容器内runtime/route/缓存不会自动刷新,必须进容器执行php think route:clear
容器网络与数据库连通性最容易被忽略的细节
很多团队在本地 Docker Compose 跑通了,上生产就连不上 MySQL,问题往往不出在代码,而在容器网络配置。TP 默认用 127.0.0.1 连数据库,但在容器里这指的是 PHP-FPM 自己,不是宿主机或另一个 MySQL 容器。
立即学习“PHP免费学习笔记(深入)”;
- TP6/TP8 的
.env必须写DB_HOST=mysql(对应 docker-compose.yml 中 service 名),不能写localhost或127.0.0.1 - 若复用宿主机 MySQL(混合部署),得用宿主机真实 IP(如
172.17.0.1),host.docker.internal在 Linux 上默认不可用,需加--add-host=host.docker.internal:host-gateway - TP 的 PDO 连接默认不启用
PDO::ATTR_EMULATE_PREPARES,MySQL 容器若没开max_allowed_packet,大批量 insert 会静默失败,错误日志只显示SQLSTATE[HY000]: General error


















