如何解决运行MySQL容器时执行数据库相关操作的问题
MySQL容器数据库操作失败排查方案
问题描述
运行MySQL容器时,执行任何数据库相关操作均失败,错误提示为连接被拒绝。使用的Docker Compose配置如下:
version: '3.8' services: splitpay-app: build: context: . dockerfile: Dockerfile.nodejs volumes: - .:/usr/src/app ports: - "8080:8080" depends_on: - mysql-db - redis environment: DB_DATABASE: ${DB_DATABASE} DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} DB_HOST: ${DB_HOST} SECRET_KEY: ${SECRET_KEY} networks: - my-networks mysql-db: build: context: . dockerfile: Dockerfile.mysql ports: - "3301:3306" expose: - "3306" volumes: - dbdata:/data/db networks: - my-networks environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} redis: build: context: . dockerfile: Dockerfile.redis ports: - "6379:6379" networks: - my-networks volumes: dbdata: networks: my-networks: driver: bridge
排查及解决步骤
1. 修正数据库连接地址
应用容器(splitpay-app)与MySQL容器处于同一Docker网络(my-networks),需用容器名mysql-db作为DB_HOST值,而非127.0.0.1或localhost。检查环境变量${DB_HOST}的配置,确保其值为mysql-db。
2. 处理MySQL启动就绪延迟
depends_on仅保证容器启动顺序,不确保MySQL服务完全就绪。可通过两种方式解决:
- 在应用启动脚本中加入等待逻辑,比如使用
wait-for-it.sh脚本检测mysql-db:3306端口连通后再启动应用; - 在应用代码中添加数据库连接重试机制,避免首次连接失败导致服务崩溃。
3. 检查MySQL用户权限配置
若应用使用的DB_USER为普通用户,需确保MySQL容器初始化时创建该用户并授权跨容器访问:
- 在
Dockerfile.mysql所在目录下创建/docker-entrypoint-initdb.d/文件夹,添加初始化SQL脚本:
CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '${DB_PASSWORD}'; GRANT ALL PRIVILEGES ON ${DB_DATABASE}.* TO '${DB_USER}'@'%'; FLUSH PRIVILEGES;
- 确保
Dockerfile.mysql将该脚本复制到容器的/docker-entrypoint-initdb.d/目录下。
4. 修正数据卷挂载路径
MySQL官方镜像默认数据存储路径为/var/lib/mysql,当前配置挂载到/data/db会导致初始化异常,修改为:
volumes: - dbdata:/var/lib/mysql
5. 排查端口占用问题
检查宿主机3301端口是否被其他进程占用:
- Linux系统执行:
netstat -tulpn | grep 3301 - Windows系统执行:
netstat -ano | findstr ":3301"
若端口被占用,修改Docker Compose中MySQL的端口映射为其他可用端口,比如3302:3306。
6. 查看MySQL容器日志定位异常
执行命令查看MySQL容器启动日志,获取具体错误信息:
docker-compose logs mysql-db
内容的提问来源于stack exchange,提问作者Dibya Ranjan
相关产品推荐
相关产品推荐

