Traefik 不处理 PHP 与 MySQL 连接,仅负责 HTTP 路由;PHP 容器需通过容器网络(同 Docker 网络、用服务名 mysql 作主机)访问 MySQL 容器,并确保 MySQL 配置 bind-address=0.0.0.0 且用户授权 'user'@'%'。

traefik 本身不处理 PHP 与 MySQL 的连接
很多人搜 traefik php mysql 连接不上,其实是混淆了职责边界:traefik 是反向代理/网关,只管 HTTP 流量路由,它不参与、也不配置 PHP 应用怎么连 MySQL。真正要查的是你的 PHP 容器(比如 php:8.2-apache)能否从容器网络访问 MySQL 容器(比如 mysql:8.0),而 traefik 只负责把外部请求转给 PHP 容器。
PHP 容器连不上 MySQL 的常见原因和检查点
典型现象是 PHP 报错:PDOException: SQLSTATE[HY000] [2002] Connection refused 或 mysqli_connect(): (HY000/2002): Connection refused。重点看这几点:
- MySQL 容器是否真的在运行?用
docker ps确认状态,不是Exited - PHP 和 MySQL 是否在同一个 Docker 网络里?
docker network inspect your-network-name查看两者是否共属一个Containers列表 - PHP 代码里写的 MySQL 主机名是不是容器名(如
mysql),而不是localhost或127.0.0.1—— 容器内localhost指自己,不是 MySQL 容器 - MySQL 是否允许远程连接?默认只监听
127.0.0.1;需在my.cnf中设bind-address = 0.0.0.0,或用 Docker 启动参数--bind-address=0.0.0.0 - MySQL 用户是否授权给对应主机?比如创建用户时用了
'user'@'localhost',但 PHP 容器 IP 不是 localhost,应改用'user'@'%'并执行FLUSH PRIVILEGES;
docker-compose.yml 中的关键配置示例
下面是最小可行的三件套(traefik + php + mysql)网络配置要点,注意注释部分:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
php:
image: php:8.2-apache
depends_on:
- mysql environment:
- MYSQL_HOST=mysql # ← 必须填 MySQL 容器名,不是 localhost
- MYSQL_USER=appuser
- MYSQL_PASSWORD=appsecret
- MYSQL_DB=appdb labels:
- "traefik.http.routers.php.rule=Host(
localhost)" networks: - appnet
mysql: image: mysql:8.0 environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=appdb
- MYSQL_USER=appuser
- MYSQL_PASSWORD=appsecret command: --default-authentication-plugin=mysql_native_password --bind-address=0.0.0.0 networks:
- appnet
← 不要暴露 3306 给宿主机,除非真需要本地客户端连;容器间通信走内部网络即可
networks: appnet: driver: bridge
验证连接是否通的最快办法
别急着改代码,先进 PHP 容器手动测试连通性:
立即学习“PHP免费学习笔记(深入)”;
- 进容器:
docker exec -itsh - 装个客户端(如果没自带):
apk add mysql-client(Alpine)或apt-get update && apt-get install -y mysql-client(Debian) - 直连测试:
mysql -h mysql -u appuser -pappsecret appdb -e "SELECT 1"—— 这里-h mysql是关键,必须用服务名 - 如果这步失败,说明网络或 MySQL 配置有问题;成功了再查 PHP 代码里的
new PDO(...)参数是否一致
最容易被忽略的是:MySQL 容器日志里有没有报错?用 docker logs 看是否启动失败、密码错误、或权限拒绝。很多“连不上”其实 MySQL 根本没起来。











