关键是要用mysql 5.7并设置--default-authentication-plugin=mysql_native_password,避免mysql 8.0的caching_sha2_password导致thinkphp连接失败;服务名mysql直连、端口映射3307:3306、.env中db_host=mysql确保容器网络互通。

在macOS上用Docker Compose为ThinkPHP项目稳定对接MySQL,关键不是拉起一个能跑的容器,而是让PHP代码能通过mysql:host=mysql;port=3306这种服务名直连、不报错、不超时、不因密码插件兼容性中断——尤其要避开MySQL 8.0默认的caching_sha2_password认证方式导致ThinkPHP连接失败的问题。
创建专用项目目录并初始化ThinkPHP结构
在终端中执行:mkdir -p ~/tp-docker/myapp && cd ~/tp-docker。
运行命令拉取ThinkPHP 8.1骨架(不依赖本地PHP环境):docker run --rm -v $(pwd)/myapp:/var/www/html composer create-project topthink/think:8.1.* .。这一步会把完整框架解压到myapp/下,【注意:必须用点号 . 作为目标路径,否则composer会在容器内新建子目录,导致宿主机映射错位】。
确认myapp/public/index.php存在且可读,这是后续Nginx入口的基础。
编写docker-compose.yml定义MySQL服务
在~/tp-docker目录下新建docker-compose.yml文件,粘贴以下内容:
version: '3.8'services: mysql: image: mysql:5.7 container_name: tp-mysql environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: thinkphp MYSQL_USER: tpuser MYSQL_PASSWORD: tppass command: --default-authentication-plugin=mysql_native_password ports: - "3307:3306" volumes: - mysql_data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpass"] timeout: 20s retries: 10volumes: mysql_data:
这里强制指定mysql:5.7镜像并追加--default-authentication-plugin=mysql_native_password参数,【这是ThinkPHP连接不报错的核心前提,MySQL 8.0默认插件会导致PDO连接直接拒绝】。
端口映射设为3307:3306,避免与Mac系统可能已启用的MySQL冲突,本地调试时用127.0.0.1:3307即可访问。
启动并验证MySQL容器状态
在~/tp-docker目录下运行:docker-compose up -d mysql。
等待约15秒后,执行:docker-compose ps,确认tp-mysql状态为healthy而非starting或unhealthy——healthcheck机制会真实检测mysqld是否就绪,比单纯看Up更可靠。
立即测试连接:docker exec -it tp-mysql mysql -uroot -prootpass -e "SHOW DATABASES;",输出中必须包含thinkphp库名,说明初始化成功。
若报错Access denied,大概率是command参数未生效或密码被覆盖,需删掉容器重试:docker-compose down && docker-compose up -d mysql。
配置ThinkPHP数据库连接参数
打开~/tp-docker/myapp/config/database.php,找到'hostname' => env('DB_HOST', '127.0.0.1')这一行,改为:'hostname' => env('DB_HOST', 'mysql')。
在~/tp-docker/myapp/.env文件中,写入以下三行:
DB_HOST=mysqlDB_PORT=3306DB_NAME=thinkphpDB_USER=tpuserDB_PWD=tppass
注意:DB_HOST必须填mysql,不能填localhost或127.0.0.1——这是Docker内部网络通信的硬性要求,容器间靠服务名解析DNS。
保存后,在myapp目录下运行:php think migrate:run(需先确保已安装migration扩展),若无报错且生成了迁移表,说明ThinkPHP已成功穿透Docker网络连上MySQL。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











