Docker部署Laravel应用报SQLSTATE[HY000] [2002] Connection refused错误
问题根因
核心错误是混淆了Docker端口映射的作用范围:
docker-compose.yaml中db服务的端口配置3309:3306,仅代表宿主机可以通过127.0.0.1:3309访问db容器的3306端口。同一个自定义Docker网络内的容器互相访问时,直接走容器内部网络,不需要走端口映射,必须使用db容器内部实际监听的3306端口。- 你在
.env中配置的DB_PORT=3309,会让Laravel在main容器内部访问db:3309,但db容器的3309端口没有任何服务监听,直接触发Connection refused错误。
其余会导致异常的配置问题:
- main服务中配置的环境变量名不符合Laravel识别规则:Laravel读取的数据库用户、库名变量为
DB_USERNAME、DB_DATABASE,当前配置的DB_USER、DB_NAME不会被Laravel加载,端口问题修复后会触发账号/库名不匹配报错。 - phpmyadmin服务的links配置指向不存在的
mysql服务,虽然当前靠PMA_HOSTS: db配置可正常连接,但属于无效配置。 docker-compose.yaml存在格式错误:顶级配置项volumes、networks前存在多余空格,phpmyadmin服务下的links字段缩进与同级字段不对齐,会导致compose启动失败。- Dockerfile中配置了Apache vhost规则,但最后启动命令是
php artisan serve调用PHP内置服务器,Apache未启动,所有vhost相关配置均为冗余无效配置。 - 配置的
WAIT_HOSTS: db:3306需要容器内安装wait-for-it类脚本才能生效,当前镜像无对应依赖,该配置不生效。
修复步骤
- 第一步:修改Laravel根目录
.env文件的数据库端口配置,确认配置如下:
DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=laravelvueblog_db DB_USERNAME=admin DB_PASSWORD=root
- 第二步:修正
docker-compose.yaml的格式错误、无效配置和环境变量,修正后完整配置如下:
version: '3.8' services: db: image: mariadb:latest container_name: db ports: - 3309:3306 environment: MYSQL_DATABASE: laravelvueblog_db MYSQL_ROOT_PASSWORD: root MYSQL_PASSWORD: root MYSQL_USER: admin volumes: - mysql_file:/docker-entrypoint-initdb.d networks: - appnetwork main: build: context: . dockerfile: Dockerfile volumes: - .:/app ports: - 8008:8000 environment: DB_HOST: db DB_PORT: 3306 DB_USERNAME: admin DB_PASSWORD: root DB_DATABASE: laravelvueblog_db depends_on: - db networks: - appnetwork phpmyadmin: image: phpmyadmin/phpmyadmin ports: - 3310:80 links: - db environment: PMA_HOSTS: db PMA_PORT: 3306 depends_on: - db networks: - appnetwork volumes: mysql_file: driver: local networks: appnetwork: driver: bridge
注:同网络下Docker Compose默认会将服务名作为DNS解析记录,links配置在新版Compose中不是必选项,可按需保留或删除。
- 第三步:(可选)清理Dockerfile中的冗余Apache配置,避免后续维护混淆,可以删除以下行:
COPY vhost.conf /etc/apache2/sites-available/000-default.conf RUN chown -R www-data:www-data /app && a2enmod rewrite RUN rm -rf /var/www/html && ln -s /app /var/www/html
如果后续需要用Apache代替PHP内置服务器,可以删除最后一行的CMD php artisan serve --host=0.0.0.0 --port=8000,将启动命令改为Apache默认启动命令,同时把端口映射改为对应Apache的80端口即可。
- 第四步:重建容器让配置生效,在
docker-compose.yaml所在目录执行以下命令:
# 停止并删除旧容器 docker compose down # 重新构建镜像并后台启动容器 docker compose up -d --build # 等待MariaDB完全启动(约10-20秒)后,进入main容器执行数据库迁移 docker compose exec main php artisan migrate
验证标准
- 数据库迁移执行成功,可正常生成migrations、users等业务表
- 访问
127.0.0.1:8008的登录等数据库交互功能,不再报Connection refused错误 - phpMyAdmin仍可通过
127.0.0.1:3310正常访问管理数据库
内容的提问来源于stack exchange,提问作者Lordwiz
相关产品推荐
相关产品推荐

