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

Docker部署环境下Web容器无法连接MySQL容器的技术求助

解决方案:MySQL容器启动失败+Web容器无法连接数据库的问题

我来帮你一步步排查并解决这两个问题:

一、MySQL容器启动失败:ERROR 1396 (HY000): Operation CREATE USER failed for 'root'@'%'

问题原因

你在docker-compose.yml的db服务环境变量里设置了MYSQL_USER: 'root',但root是MySQL默认自带的超级用户,不需要通过MYSQL_USER环境变量重复创建,所以容器启动时执行创建用户的命令就会直接报错,导致容器退出。

解决方法

二选一即可:

  • 如果不需要额外的普通数据库用户:直接删除MYSQL_USER: 'root'和对应的MYSQL_PASSWORD: 'password'这两行环境变量;
  • 如果需要创建额外用户:把MYSQL_USER改成其他非root的用户名(比如db_admin),同时调整后续数据库连接的用户名(如果用这个用户连接的话)。

修改后的db服务环境变量示例(删除额外用户的情况):

services:
  db:
    image: mysql:5.7
    ports:
      - '3306:3306'
    environment:
      MYSQL_DATABASE: 'DBM'
      MYSQL_ROOT_PASSWORD: 'password'

二、Web容器无法连接MySQL:MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")

这个问题有两个核心原因,我们逐个解决:

1. 数据库连接的Host配置错误

你提到把host改成了src_db_1,但在你的docker-compose.yml里,db服务的名称是db——在Docker Compose的默认网络中,服务名称可以直接作为域名解析到对应容器,用服务名比容器名(通常是<项目目录名>_db_1)更可靠,不会因为项目目录变化而失效。

所以你需要把Python连接代码里的host改成db:

db = MySQLdb.connect(host="db", user="root", passwd="password", db="DBM", port=3306)

2. Web容器启动时MySQL服务还未就绪

depends_on: - db只是保证db容器先启动,但不保证MySQL服务已经完成初始化、可以接受连接。当Web容器启动并尝试连接时,MySQL可能还在初始化数据库,导致连接失败。

解决方法(二选一)

方法一:用等待脚本确保MySQL就绪

我们可以用wait-for-it脚本让Web容器等待MySQL服务完全就绪后再启动:

  • 首先修改你的Dockerfile,添加安装wait-for-it的步骤:
FROM python:3.8
ENV PYTHONUNBUFFERED 1
RUN mkdir /api_rest_mix_1_0
WORKDIR /api_rest_mix_1_0
# 安装wait-for-it工具
RUN apt-get update && apt-get install -y wait-for-it
ADD requirements.txt /api_rest_mix_1_0/
RUN pip install --upgrade pip && pip install -r requirements.txt
ADD . /api_rest_mix_1_0/
  • 然后修改docker-compose.yml里Web服务的command:
services:
  web:
    build: .
    command: wait-for-it db:3306 -- python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/my_app_dir
    ports:
      - "8000:8000"
    depends_on:
      - db

方法二:在Python代码中添加连接重试逻辑

如果不想安装额外工具,可以在数据库连接的代码里添加重试逻辑,比如:

import time
import MySQLdb

def get_db_connection():
    while True:
        try:
            db = MySQLdb.connect(host="db", user="root", passwd="password", db="DBM", port=3306)
            return db
        except MySQLdb._exceptions.OperationalError:
            print("MySQL not ready yet, waiting 2 seconds...")
            time.sleep(2)

# 使用这个函数获取连接
db = get_db_connection()

最终验证步骤

  1. 先清理现有容器和数据卷(确保MySQL重新初始化):
docker-compose down -v
  1. 应用上面所有修改到对应的文件;
  2. 重新构建并启动容器:
docker-compose up --build

这样就能解决你的两个问题了。

内容的提问来源于stack exchange,提问作者Marco Antonio Bet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:42:35