You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker化Symfony 4.2项目无法连接MySQL容器问题求助

Symfony 4.2 Docker化后数据库连接拒绝问题

问题现象

将Symfony 4.2项目迁移至Docker容器,搭配MySQL 8.0(因Mac M1不支持5.4/5.7版本),但项目始终无法连接数据库。php-apache容器日志及浏览器均抛出相同错误:

Uncaught PHP Exception Doctrine\DBAL\Exception\ConnectionException: "An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused"

已执行的部署操作

  • 拉取php-apache-7.4镜像
  • 拉取MySQL 8.0镜像
  • 在docker-compose.yml中配置MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
  • 在php-apache容器中安装pdo、mysqli、pdo_mysql和zip扩展
  • 生成并安装自签名SSL证书至php-apache容器
  • 暴露端口:3306(MySQL)、80(Web)、443(SSL)
  • 在docker-compose.yml中创建自定义网络abc-network
  • 本地/etc/hosts添加测试域名并重启Apache

配置文件内容

docker-compose.yml

version: "3.8"

networks:
  abc-network:

services:
  #mysql
  mysql-service:
    image: mysql
    networks:
      - abc-network
    container_name: abc_db_container
    ports:
      - "3306:3306"

    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    volumes:
      - ./mysql:/var/lib/mysql
    restart: always

  #php
  php-service:
    build:
      context: .
      dockerfile: ./symfony/Dockerfile
    container_name: abc_php_container
    networks:
      - abc-network
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./symfony/docker/ssl/mycert.crt:/etc/ssl/certs/mycert.crt
      - ./symfony/docker/ssl/mycert.key:/etc/ssl/private/mycert.key
      - ./symfony:/var/www/symfony
    depends_on:
      - mysql-service

Dockerfile

# PHP + Apache
FROM php:7.4-apache

#Enable apache module and ssl self sign installation
RUN a2enmod rewrite
RUN a2enmod ssl && a2enmod socache_shmcb
RUN sed -i '/SSLCertificateFile.*snakeoil\.pem/c\SSLCertificateFile \/etc\/ssl\/certs\/mycert.crt' /etc/apache2/sites-available/default-ssl.conf && sed -i '/SSLCertificateKeyFile.*snakeoil\.key/cSSLCertificateKeyFile /etc/ssl/private/mycert.key\' /etc/apache2/sites-available/default-ssl.conf
RUN a2ensite default-ssl
RUN apt-get update && apt-get upgrade -y


#updates apt get and install essential php libraries
RUN apt-get update \
  && apt-get install -y libzip-dev git wget --no-install-recommends \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

#Install mysql driver for php and zip
RUN docker-php-ext-install pdo mysqli pdo_mysql zip;

#Installs composer
RUN wget https://getcomposer.org/download/2.0.9/composer.phar \
    && mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer

RUN chmod 777 /var/lib

#Copies ABC's virtual host conf file to the docker container
COPY ./symfony/docker/apache.conf /etc/apache2/sites-enabled/000-default.conf
COPY ./symfony/docker/ssl-conf.conf /etc/apache2/sites-available/default-ssl.conf
#Copies ABC CMS Symfony project
COPY ./symfony /var/www/symfony/

#Points the working directory
WORKDIR /var/www/symfony

CMD ["apache2-foreground"]

解决方法

1. 修正Symfony数据库主机配置

Docker容器间通过服务名通信,Symfony的.env或config/packages/doctrine.yaml中,数据库主机不能填localhost或127.0.0.1,需替换为docker-compose中MySQL的服务名mysql-service:

# .env文件示例
DATABASE_URL=mysql://root@mysql-service:3306/你的数据库名?serverVersion=8.0

2. 确保MySQL服务就绪后启动PHP容器

depends_on仅保证容器启动顺序,不确保MySQL服务完全就绪。可添加健康检查解决:
在docker-compose.yml的mysql-service中加入健康检查配置:

healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
  timeout: 20s
  retries: 10

然后修改php-service的depends_on:

depends_on:
  mysql-service:
    condition: service_healthy

3. 兼容MySQL 8.0认证机制

MySQL 8.0默认使用caching_sha2_password认证,部分旧PHP客户端不兼容。在mysql-service的环境变量中添加:

environment:
  MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
  MYSQL_DEFAULT_AUTH: mysql_native_password

4. 检查端口冲突

确认本地3306端口未被其他MySQL服务占用,若有冲突可修改docker-compose中MySQL的端口映射为3304:3306,容器内部仍使用3306端口。

5. 验证容器网络连通性

进入php-apache容器,测试能否ping通MySQL服务:

docker exec -it abc_php_container ping mysql-service

若不通,检查两个容器是否都加入了abc-network网络。

内容的提问来源于stack exchange,提问作者Olayinka Sagoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:16:17