使用Docker-Compose部署PHP+MySQL应用时连接被拒绝求助
问题诊断与解决方案
核心原因
- 容器网络隔离:PHP容器内的
127.0.0.1指向容器自身,而非MySQL容器。Docker Compose创建的自定义网络中,每个服务的名称(如mysql)是可直接解析的网络别名。 - 连接时序问题:PHP容器启动速度快于MySQL初始化进程,可能在MySQL未就绪时发起连接,导致拒绝。
分步解决方案
1. 修改PHP连接代码
将index.php中的数据库主机地址改为服务名mysql:
<?php mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 用docker-compose服务名mysql替代127.0.0.1 $connection = new mysqli('mysql', 'root', 'password'); ?>
2. 优化Docker Compose配置(可选但推荐)
添加MySQL健康检查,确保PHP容器在MySQL完全就绪后再启动:
version: "3.9" services: php: container_name: php2 image: php restart: always build: context: . dockerfile: DockerfilePHP target: base networks: - backend ports: - "${PHPPORT}:80" # 等待MySQL健康检查通过后启动 depends_on: mysql: condition: service_healthy mysql: build: context: . dockerfile: DockerfileMysql environment: MYSQL_ROOT_PASSWORD: password ports: - "${MYSQLPORT}:3306" networks: - backend # 添加健康检查 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 5 networks: backend: driver: bridge
3. 简化配置(可选)
你的MySQL Dockerfile仅继承官方镜像,可直接移除该文件,在docker-compose.yml中直接使用官方镜像:
mysql: image: mysql:latest # 替换build部分为直接使用官方镜像 environment: MYSQL_ROOT_PASSWORD: password ports: - "${MYSQLPORT}:3306" networks: - backend healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 5
验证步骤
- 停止并清理现有容器:
docker-compose down - 重新构建并启动服务:
docker-compose up --build - 访问
http://localhost:44445,确认连接错误消失。
内容的提问来源于stack exchange,提问作者Nikita Nikiforov
相关产品推荐
相关产品推荐

