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

Docker部署Django+MySQL报(2002)mysqld.sock连接错误如何解决

问题根因

你遇到的socket连接错误核心原因是web容器内的Django读取到的MySQL HOST配置为localhost,尝试连接容器自身的MySQL服务(而非名为db的数据库容器),才会去找unix socket文件。叠加配置里的多处笔误、规则理解偏差,最终导致连接失败。
最常见的触发场景是:本地开发时项目内的.env文件配置了HOST=localhost,部署时没有修改,同时你误以为docker-compose会自动把根目录.env的配置注入容器,没有显式传参,Django加载到本地配置后就会走本地socket连接逻辑。

分步修复方案

1. 修正docker-compose.yml配置

首先纠正几个配置错误:

  • 根目录的.env默认只用于解析yml文件内的变量占位,不会自动注入服务容器,必须在web服务下显式声明env_file加载
  • 数据库初始化脚本的挂载路径存在笔误:docker-entrypoint-initbd.d应为docker-entrypoint-initdb.d(b、d顺序写反),另外你写的.setup.sql是隐藏文件路径,正常应该加载当前目录下的./setup.sql
  • 废弃的links配置可以直接删除,新版Compose默认会在同一网络下用服务名做DNS解析,不需要手动配置链路
  • depends_on仅能保证db容器先启动,不会等待MySQL服务初始化完成,需要加健康检查避免web服务提前启动连库失败
  • 给MySQL数据目录加命名卷持久化,避免容器删除后数据丢失
  • MySQL8默认的密码插件兼容性差,加启动参数指定为mysql_native_password,避免mysqlclient认证失败

修正后的完整配置参考:

version: '3'

services: 
  db:
    image: mysql:8
    ports:
      - '3306:3306'
    environment:
       MYSQL_DATABASE: 'database_name'
       MYSQL_USER: 'django'
       MYSQL_PASSWORD: 'django-password'
       MYSQL_ROOT_PASSWORD: 'password'
    volumes:
      - ./setup.sql:/docker-entrypoint-initdb.d/setup.sql
      - mysql_data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-ppassword"]
      interval: 5s
      timeout: 5s
      retries: 10

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    env_file: .env
    depends_on:
      db:
        condition: service_healthy

volumes:
  mysql_data:

2. 修正Django数据库配置

你当前的配置存在两个小问题:

  • os.environ.get读取的环境变量是字符串类型,PORT参数建议显式转整数,避免类型兼容问题
  • 如果你用了python-dotenv等库自动加载项目内的.env文件,确认文件内的MYSQL_DATABASE_HOST值为db而非localhost,否则会覆盖默认配置
  • 可以补充utf8mb4编码配置,避免中文存储乱码

修正后的配置参考:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('MYSQL_DATABASE', 'database_name'),
        'USER': os.environ.get('MYSQL_USER', 'django'),
        'PASSWORD': os.environ.get('MYSQL_PASSWORD', 'django-password'),
        'HOST': os.environ.get('MYSQL_DATABASE_HOST', 'db'),
        'PORT': int(os.environ.get('MYSQL_DATABASE_PORT', 3306)),
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}

注意:只要HOST参数不是localhost或空字符串,mysqlclient就会走TCP协议连接指定主机,不会去找本地socket文件,这是解决你当前报错的核心逻辑。

3. 修正Dockerfile配置

你当前的Dockerfile有冗余配置,还缺少mysqlclient依赖的系统包,直接pip安装会报编译错误:

  • 重复的代码拷贝命令保留一个即可,COPY语义比ADD更明确,优先用COPY
  • 提前安装default-libmysqlclient-dev、build-essential两个系统依赖,否则mysqlclient安装失败

修正后的Dockerfile参考:

FROM python:3.8
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y default-libmysqlclient-dev build-essential && rm -rf /var/lib/apt/lists/*
WORKDIR /code
RUN pip install --upgrade pip
COPY requirements.txt /code/
RUN pip install -r requirements.txt && pip install mysqlclient
COPY . /code/

4. 清理旧配置重新启动

改完所有配置后,必须清理旧容器和匿名卷,避免缓存的旧配置影响结果:

docker-compose down -v
docker-compose up -d --build
验证方法

启动后按顺序检查:

  1. 执行docker-compose logs db,看到ready for connections字样说明MySQL正常启动
  2. 执行docker-compose exec web env | grep MYSQL_DATABASE_HOST,确认输出值为db,没有被错误覆盖为localhost
  3. 执行docker-compose exec web python manage.py migrate,能正常执行数据库迁移就说明连库成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:21:37