Docker部署PHP+MySQL网站数据库连接失败求助(错误SQLSTATE[HY000][2002])
问题分析与解决方案
你的数据库连接报错SQLSTATE[HY000] [2002] No such file or directory,核心原因是Docker容器间通信配置错误,加上docker-compose.yaml存在冗余服务,导致PHP无法正确寻址到MySQL容器。以下是具体修正步骤:
1. 清理冗余的Docker Compose配置
你的docker-compose.yaml里同时定义了php-apache-environment和myweb两个PHP服务,属于重复配置,且myweb的hostname: localhost会干扰容器间的服务发现。简化后的配置如下:
version: '3.8' services: db: container_name: db image: mysql:8.0 # 指定稳定版本,避免兼容性问题 restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: ShoppingWebDB MYSQL_USER: root MYSQL_PASSWORD: root volumes: - mysql_data:/var/lib/mysql # 持久化数据库数据,防止容器删除丢失 # 本地客户端需要连接时再放开端口,容器间通信无需暴露 # ports: # - "9906:3306" myweb: container_name: myweb build: context: . dockerfile: Dockerfile restart: always ports: - '8080:80' volumes: - .:/var/www/html/ # 开发阶段挂载代码目录,方便实时修改 environment: # 给PHP传递数据库连接参数,便于代码复用 DB_HOST: db DB_NAME: ShoppingWebDB DB_USER: root DB_PASS: root depends_on: - db volumes: mysql_data:
2. 修正PHP代码的数据库连接逻辑
报错的本质是:当PHP连接地址写localhost时,会优先尝试Unix Socket连接,但Docker容器内不存在MySQL的Socket文件。必须改用Docker Compose的服务名db作为数据库主机(Compose会自动在内部网络解析该名称到MySQL容器)。
示例PDO连接代码:
// 从环境变量读取配置,或直接硬编码(开发环境) $dbHost = getenv('DB_HOST') ?: 'db'; $dbName = getenv('DB_NAME') ?: 'ShoppingWebDB'; $dbUser = getenv('DB_USER') ?: 'root'; $dbPass = getenv('DB_PASS') ?: 'root'; try { $pdo = new PDO( "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass ); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { die("Failed to connect DB: " . $e->getMessage()); }
3. 重新部署服务
执行以下命令清理旧容器并启动新服务:
# 停止并删除旧容器、卷 docker-compose down -v # 构建镜像并启动服务(-d 后台运行) docker-compose up --build -d # 查看服务日志,确认启动状态 docker-compose logs myweb docker-compose logs db
额外说明
depends_on仅保证MySQL容器先启动,但不保证MySQL服务完全初始化完成。如果PHP启动时MySQL还未就绪,可能会出现短暂连接失败,开发环境可手动重启myweb容器,生产环境可添加连接重试逻辑。- 若需要用phpMyAdmin管理数据库,可在
docker-compose.yaml中添加phpmyadmin服务,配置PMA_HOST: db即可。
内容的提问来源于stack exchange,提问作者Emmm
相关产品推荐
相关产品推荐

