Symfony 4 搭配Docker容器时出现SQLSTATE[HY000] [2002]连接拒绝错误
我之前也踩过这个坑,核心问题其实是Docker容器间的网络逻辑和宿主机不一样,咱们一步步来排查解决:
1. 修正Symfony的数据库配置
你本地能连localhost:3321是因为宿主机把端口映射到了db容器,但在web容器(apache-symfony-4)里,localhost指的是它自己,不是你的Mac主机,也不是db容器。
你需要把Symfony配置里的数据库主机改成Docker Compose里的服务名db,端口用容器内部的3306(不是宿主机的3321)。
打开你的.env文件(或者config/packages/doctrine.yaml),修改DATABASE_URL:
# 替换成你实际的用户名、密码和数据库名 DATABASE_URL=mysql://your_db_user:your_db_password@db:3306/your_db_name?serverVersion=5.7
注意:这里的用户名、密码、数据库名必须和你db容器Dockerfile里设置的环境变量一致(比如MYSQL_USER、MYSQL_PASSWORD、MYSQL_DATABASE)。
2. 确认db容器的环境变量配置
检查./docker/db/目录下的Dockerfile,确保它设置了正确的初始化环境变量,比如:
# 示例配置,根据你的实际需求修改 ENV MYSQL_ROOT_PASSWORD=root_password ENV MYSQL_USER=symfony_user ENV MYSQL_PASSWORD=symfony_pass ENV MYSQL_DATABASE=symfony_project_db
如果没有这些配置,db容器不会自动创建你需要的用户和数据库,自然会连接失败。
3. 确保db服务完全就绪后再启动web
你的depends_on只保证启动顺序,不保证db服务已经完全可用(比如MySQL还没完成初始化)。可以给db服务加健康检查,确保它就绪后再启动web:
修改你的docker-compose.yml:
version: '2' volumes: db_data: {} services: db: container_name: database-mysql-5.7 build: context: ./docker/db/ ports: - "3321:3306" volumes: - db_data:/var/lib/mysql # 添加健康检查 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] timeout: 20s retries: 10 web: container_name: apache-symfony-4 build: context: ./docker/web/ image: php links: - db depends_on: # 等待db服务健康就绪 db: condition: service_healthy ports: - "8021:80" volumes: - ./app/:/var/www/symfony
4. 清理Symfony缓存
Symfony可能缓存了旧的数据库配置,一定要清理缓存:
# 进入web容器执行 docker exec -it apache-symfony-4 bash # 开发环境 php bin/console cache:clear --env=dev # 生产环境 php bin/console cache:clear --env=prod
或者直接删除web容器里的var/cache目录也行。
验证容器间连通性(可选)
如果还是有问题,可以进入web容器测试和db的连通性:
docker exec -it apache-symfony-4 bash # 测试ping db服务 ping db # 测试3306端口是否开放 telnet db 3306
如果ping不通或者telnet失败,检查Docker Compose的网络配置,默认情况下同一compose里的服务是在同一个网络里的,应该能互通。
内容的提问来源于stack exchange,提问作者notronwest

