Docker Compose中后端连接MySQL容器报Access Denied错误的排查与解决
问题描述
使用docker-compose部署frontend、backend、mysql三个容器,后端通过Python的mysql.connector连接mysql容器时,出现Access Denied错误,backend容器以代码1退出。相关配置及代码如下:
docker-compose.yml
version: '3' services: mydb: container_name: mydb image: mysql env_file: - .env.mysql volumes: - ./mysqld:/var/run/mysqld - ./db:/var/lib/mysql ports: - "3306:3306" environment: - MYSQL_ROOT_HOST:% healthcheck: test: "mysqladmin ping -h localhost" interval: 1s timeout: 1s retries: 60 backend: container_name: backend build: context: . dockerfile: back-dockerfile ports: - "90:90" depends_on: - mydb frontend: container_name: frontend build: context: . dockerfile: front-dockerfile ports: - "8501:8501"
.env.mysql
MYSQL_ROOT_PASSWORD=123456 MYSQL_ROOT_HOST=% MYSQL_DATABASE=eass
后端连接代码
import mysql.connector db = mysql.connector.connect( host="mydb", user="root", passwd="123456", database="eass", auth_plugin='mysql_native_password' )
解决方案
1. 让后端等待MySQL完全就绪
默认depends_on仅保证MySQL容器启动,不代表数据库服务已就绪。需修改配置让后端依赖MySQL的健康检查状态:
- 将docker-compose的
version升级为3.8(该版本支持健康检查依赖) - 修改backend的
depends_on配置:
backend: # 其他配置不变 depends_on: mydb: condition: service_healthy
同时修正MySQL的健康检查命令,需带上密码才能成功验证:
mydb: # 其他配置不变 healthcheck: test: "mysqladmin ping -h localhost -u root -p$$MYSQL_ROOT_PASSWORD" interval: 2s timeout: 2s retries: 30
2. 清理旧MySQL数据卷(关键)
若之前启动过MySQL容器,本地挂载的./db目录可能残留旧的用户权限配置,导致新环境变量不生效。执行以下命令清理:
docker-compose down rm -rf ./db ./mysqld docker-compose up --build
3. 移除重复环境变量配置
docker-compose中environment字段会覆盖env_file的同名变量,当前配置中MYSQL_ROOT_HOST重复设置,建议删除docker-compose里environment下的- MYSQL_ROOT_HOST:%,仅保留env_file的配置,避免冲突。
4. 验证连接参数
后端代码中host: "mydb"配置正确(docker-compose服务名可作为内部DNS解析),确认user、passwd、database与.env.mysql中的配置完全一致。
内容的提问来源于stack exchange,提问作者MopyKing
相关产品推荐
相关产品推荐

