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

Docker部署Django与MariaDB:容器运行后迁移命令执行失败求助

Django容器构建时迁移正常,运行后执行迁移报错的问题排查与解决

问题现象

  • MariaDB/MySQL与Django分别通过独立docker-compose.yml部署为容器,二者处于同一Docker网络但IPv4地址不同
  • 执行docker-compose build构建Django容器时,Dockerfile中定义的python manage.py makemigrations和migrate命令执行成功,MariaDB容器内可看到初始迁移记录
  • 容器启动后,通过docker exec -ti <django-container-name> bash进入容器执行相同迁移命令,报1045 (28000): Access denied for user '<user>'@'<host>' (using password: YES)错误
  • Django容器内执行mysql相关命令时,提示bash错误(mysql客户端未安装)

核心原因分析

  1. 数据库用户权限范围限制
    MariaDB/MySQL的用户权限基于用户名@允许访问的主机规则。构建Django容器时,构建阶段的容器默认不在自定义Docker网络中,IP与运行时容器的IP完全不同;即使同网络,容器重启后IP也可能动态变化。若数据库用户仅授权了构建时的IP访问,运行时新IP不在授权列表内,就会触发权限拒绝错误。

  2. 构建与运行阶段的数据库连接配置不一致
    若Dockerfile构建时,Django的数据库HOST配置指向宿主机(如host.docker.internal或宿主机物理IP),而运行时配置改为MariaDB容器名(同网络下通过容器名解析),但数据库用户未授权用户名@<Django容器IP>或用户名@%(允许任意主机)访问,就会导致连接失败。

  3. Django容器未预装MySQL客户端
    这只是执行mysql命令报错的原因,与迁移失败无关,属于额外的环境缺失问题。


解决步骤

1. 调整数据库用户权限

进入MariaDB容器,执行SQL命令扩展用户的访问权限:

-- 允许用户从任意主机访问(生产环境建议限制为Docker子网,更安全)
GRANT ALL PRIVILEGES ON <你的Django数据库名>.* TO '<数据库用户名>'@'%' IDENTIFIED BY '<数据库密码>';
-- 刷新权限使配置生效
FLUSH PRIVILEGES;

若需严格权限控制,可指定Django容器所在的Docker子网(例如自定义网络子网为172.18.0.0/16):

GRANT ALL PRIVILEGES ON <你的Django数据库名>.* TO '<数据库用户名>'@'172.18.0.%' IDENTIFIED BY '<数据库密码>';
FLUSH PRIVILEGES;

2. 统一构建与运行阶段的数据库连接配置

确保Djangosettings.py中的数据库HOST配置在构建和运行阶段一致,建议使用MariaDB容器名(同Docker网络下可直接解析):

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '<你的Django数据库名>',
        'USER': '<数据库用户名>',
        'PASSWORD': '<数据库密码>',
        'HOST': 'mariadb',  # 替换为你的MariaDB容器名
        'PORT': '3306',
    }
}

同时,让构建阶段的Django容器加入自定义Docker网络,确保构建时能通过容器名访问MariaDB:
在Django的docker-compose.yml中添加构建网络配置:

version: '3.8'
services:
  django:
    build:
      context: .
      network: your_custom_network  # 指定与MariaDB容器相同的自定义网络
    networks:
      - your_custom_network
networks:
  your_custom_network:
    external: true  # 假设该网络已由MariaDB的docker-compose创建

或构建时通过命令指定网络:

docker-compose build --network your_custom_network

3. (可选)在Django容器中安装MySQL客户端

若需要在容器内执行mysql命令,可在Dockerfile中添加安装步骤:

  • 基于Debian/Ubuntu镜像:
RUN apt-get update && apt-get install -y --no-install-recommends mysql-client && rm -rf /var/lib/apt/lists/*
  • 基于Alpine镜像:
RUN apk add --no-cache mysql-client

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:05:08