ThinkPHP 8.2 部署必须使用 PHP ≥ 8.1,且需在容器中显式启用 pdo、mbstring、xml 扩展;Docker 环境下须用 nginx + php-fpm 分离架构,nginx root 指向 public/,数据库 host 填服务名 db 而非 localhost。

ThinkPHP 8.2 要求 PHP ≥ 8.1,不能用 php:8.2-apache 镜像直接跑——它默认没开 pdo、mbstring、xml 这三个硬依赖扩展,一启动就报 Class not found 或空白页。必须定制或补全扩展。
确认本地 Docker 已就绪
别跳过这步:Docker Desktop 必须正在运行(菜单栏有小鲸鱼图标且状态稳定)。终端执行 docker --version 和 docker-compose --version 都要有输出。若提示 command not found,说明 Docker Desktop 没装好或没启动;不是 Homebrew 装的 docker CLI 替代品。
用 docker-compose 启动 nginx + php-fpm 组合(推荐)
单容器(如 php:8.2-apache)看着省事,但 ThinkPHP 的路由、静态资源、错误日志都难调。分离部署更可控,也贴合生产结构。
- 在项目根目录新建
docker-compose.yml,内容如下(已适配 Apple Silicon / Intel):
version: "3.8"
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
<p>php:
image: php:8.2-fpm-alpine
volumes:</p><ul><li>./:/var/www/html<h1>关键:启用 ThinkPHP 必需的扩展</h1><p>command: sh -c "docker-php-ext-install pdo pdo_mysql mbstring xml && php-fpm"
- 同级目录建
nginx.conf,确保支持index.php入口和 URL 重写:
server {
listen 80;
root /var/www/html/public; # ThinkPHP 8 默认入口在 public/
index index.php;
</li></ul><pre class="brush:php;toolbar:false;">location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}}
- 执行
docker-compose up -d启动;访问http://localhost:8080,应看到 ThinkPHP 欢迎页
数据库连接必须用容器名,不是 localhost
ThinkPHP 的 .env 里数据库配置别写 host=127.0.0.1 或 host=localhost——这是容器内视角,指向自己,连不上 MySQL。
立即学习“PHP免费学习笔记(深入)”;
- 加一个
db服务到docker-compose.yml中(放在php下方):
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: tp8dev
MYSQL_DATABASE: thinkphp
volumes:
- ./mysql-data:/var/lib/mysql
ports:
- "3306:3306"
- 然后在 ThinkPHP 的
.env里写:DB_HOST=db(不是 localhost)、DB_PORT=3306、DB_NAME=thinkphp、DB_USER=root、DB_PASS=tp8dev - 容器间通过服务名自动 DNS 解析,
php容器能直接用db当主机名连 MySQL
常见失败点和绕不过去的细节
很多问题不是代码错,是环境链路断了:
-
phpinfo()能看,但 ThinkPHP 报Class 'PDO' not found→ 说明pdo扩展没真正加载进运行时,检查command是否执行成功,或改用Dockerfile显式安装 - 页面 502 Bad Gateway →
web容器连不上php容器的 9000 端口,确认depends_on存在,且php-fpm进程确实在跑(docker-compose exec php ps aux | grep fpm) - 修改 PHP 代码后不生效 → 确保
volumes挂载的是整个项目目录(含public/),不是只挂public/;ThinkPHP 8 的app目录也在根下 -
composer install在宿主机跑,但容器里没装扩展 → 不要在容器外装依赖。所有vendor/应该由容器内 Composer 生成,或用多阶段构建,否则扩展缺失导致运行时报错
最易被忽略的是:ThinkPHP 8.2 的 public/ 是 Web 入口,nginx.conf 的 root 必须指向它,而不是项目根目录;少这一层,所有路由和静态资源都会 404。



















