Docker部署Laravel连接MySQL报root访问被拒问题排查
Docker部署Laravel连接MySQL失败修复
现有配置
docker-compose.yml
version: "3.7" services: app: build: args: user: sammy uid: 1000 context: ./ dockerfile: Dockerfile image: travellist container_name: travellist-app restart: unless-stopped working_dir: /var/www/ volumes: - ./:/var/www networks: - travellist db: image: 'mysql:latest' restart: 'unless-stopped' ports: - '3306:3306' environment: - 'MYSQL_RANDOM_ROOT_PASSWORD=true' - 'MYSQL_DATABASE=${DB_DATABASE}' - 'MYSQL_USER=${DB_USER}' - 'MYSQL_PASSWORD=${DB_PASSWORD}' - 'MYSQL_ALLOW_EMPTY_PASSWORD=true' volumes: - 'laravel-database:/var/lib/mysql/' networks: - travellist nginx: image: nginx:alpine container_name: travellist-nginx restart: unless-stopped ports: - 8000:80 volumes: - ./:/var/www - ./docker-compose/nginx:/etc/nginx/conf.d/ networks: - travellist networks: travellist: driver: bridge volumes: laravel-database:
Dockerfile
FROM php:7.4-fpm # 引入docker-compose.yml中定义的参数 ARG user ARG uid # 安装系统依赖 RUN apt-get update && apt-get install -y \ git \ curl \ libpng-dev \ libonig-dev \ libxml2-dev \ zip \ unzip # 清理安装缓存 RUN apt-get clean && rm -rf /var/lib/apt/lists/* # 安装PHP扩展 RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd # 安装最新版Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # 创建运行Composer和Artisan命令的系统用户 RUN useradd -G www-data,root -u $uid -d /home/$user $user RUN mkdir -p /home/$user/.composer && \ chown -R $user:$user /home/$user # 设置工作目录 WORKDIR /var/www USER $user
运行状态与报错
执行docker-compose up后所有容器显示为运行状态,docker-compose ps输出如下:
Name Command State Ports --------------------------------------------------------------------------------------------------------------- proj_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp,:::3306->3306/tcp, 33060/tcp travellist-app docker-php-entrypoint php-fpm Up 9000/tcp travellist-nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp,:::8000->80/tcp
存在两类连接错误:
- Laravel应用连接报错:
local.ERROR: SQLSTATE[HY000] [1045] Access denied for user 'root'@'172.19.0.3' (using password: YES)
- TablePlus本地连接报错:
Lost connection to MySQL server at 'waiting for initial communication packet', system error: 10060
当前Laravel项目.env数据库配置:
DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=here_goes_db_name DB_USERNAME=root DB_PASSWORD=tyutyu
问题原因
- MySQL容器环境变量配置冲突:同时开启了
MYSQL_RANDOM_ROOT_PASSWORD(随机生成root密码)、MYSQL_ALLOW_EMPTY_PASSWORD(允许root空密码登录),和预期的固定root密码逻辑互斥;同时配置的MYSQL_USER、MYSQL_PASSWORD变量在.env中不存在(.env中定义的是DB_USERNAME),自定义用户也无法正常创建。 - MySQL版本兼容问题:
mysql:latest当前为8.x版本,默认使用caching_sha2_password身份认证插件,PHP7.4自带的pdo_mysql扩展、旧版TablePlus均不支持该认证方式,会导致连接被拒绝、通信包等待超时的报错。 - 旧数据卷持久化了错误初始化的MySQL数据,修改配置后不删除旧卷不会触发重新初始化,配置无法生效。
修复步骤
- 修改docker-compose.yml中db服务配置,解决冲突与兼容问题,修改后的db段配置如下:
db: image: 'mysql:5.7' restart: 'unless-stopped' ports: - '3306:3306' environment: - 'MYSQL_ROOT_PASSWORD=${DB_PASSWORD}' - 'MYSQL_DATABASE=${DB_DATABASE}' volumes: - 'laravel-database:/var/lib/mysql/' networks: - travellist command: --default-authentication-plugin=mysql_native_password # 若坚持使用mysql8.x镜像保留该行,使用mysql5.7可删除
若要使用mysql8.x版本,把镜像改回
mysql:latest同时保留上方command配置即可,PHP7.4和TablePlus可正常连接。
- 停止容器并删除旧的持久化数据卷,清除错误初始化的数据(新部署环境无存量数据可直接执行,有存量数据提前备份):
docker-compose down -v
- 确认Laravel
.env配置保持如下内容,DB_HOST必须填docker-compose中数据库服务的名称db,容器内部网络通过服务名做域名解析:
DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=here_goes_db_name DB_USERNAME=root DB_PASSWORD=tyutyu
- 重新构建并启动容器:
docker-compose up -d --build
- 等待10-20秒待MySQL完成初始化后验证连接:
- Laravel侧执行
docker-compose exec app php artisan migrate,无报错即代表应用与数据库连接正常 - TablePlus连接参数:主机填
127.0.0.1,端口3306,用户名root,密码tyutyu,选择对应数据库即可正常登录管理。
内容的提问来源于stack exchange,提问作者Amithash
相关产品推荐
相关产品推荐

