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

Docker部署Django无法连接MariaDB(dj1_mariadb)求助

Django容器无法连接MariaDB的问题排查与解决

问题描述

使用Docker Compose部署Django、MariaDB和phpMyAdmin环境时,http://localhost:8080/(phpMyAdmin)可正常访问,但Django容器无法连接MariaDB数据库。执行命令:

docker-compose run dj1_web python3 manage.py inspectdb

抛出错误:

django.db.utils.OperationalError: (2002, "Can't connect to server on 'dj1_mariadb' (115)")

项目目录结构

📄 Dockerfile
📄 .env
📄 requirements.txt
📁 pr/
  📁 static/
    📄 app.js
  📄 manage.py
  📁 pr/
    📄 wsgi.py
    📄 __init__.py
    📄 urls.py
    📄 settings.py
    📄 asgi.py
📄 docker-compose.yml

关键配置文件内容

Dockerfile

# 使用官方Python镜像作为基础镜像
# syntax=docker/dockerfile:1
FROM python:3.11

# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# 安装系统依赖
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
       gcc \
       libmariadb-dev \
    && rm -rf /var/lib/apt/lists/*

# 升级pip
RUN pip install --upgrade pip

# 设置工作目录
WORKDIR /app

# 安装Python依赖
COPY requirements.txt /app/
RUN pip install -r requirements.txt

# 复制项目代码到容器内
COPY ./pr /app/
# 暴露Django开发服务器端口
EXPOSE 8000

requirements.txt

psycopg2>=2.8
asgiref==3.8.1
Django==5.1.1
djangorestframework==3.15.2
mysqlclient==2.2.4
python-dotenv==1.0.1
sqlparse==0.5.1
pytz==2024.2

settings.py(数据库配置片段)

....
# 数据库配置
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('MYSQL_DATABASE'),
        'USER': os.environ.get('MYSQL_USER'),
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
        'HOST': 'dj1_mariadb',
        'PORT': 3306,
    }
}
....

docker-compose.yml

services:

  dj1_mariadb:
    image: mariadb:latest
    container_name: dj1_mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: myrpass
      MYSQL_DATABASE: dj1
      MYSQL_USER: ab_usr
      MYSQL_PASSWORD: mypass
    volumes:
      - ./data/mariadb:/var/lib/mysql
      # apt-get update && apt-get install -y mariadb-client
    networks:
      - app-network

  dj1_pma:
    image: phpmyadmin/phpmyadmin
    container_name: dj1_pma
    restart: always
    environment:
      PMA_HOST: dj1_mariadb
      PMA_USER: ab_usr
      PMA_PASSWORD: mypass
    ports:
      - "8080:80"
    depends_on:
      - dj1_mariadb
    networks:
      - app-network


  dj1_web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: dj1_web
    command: >
      sh -c "python3 manage.py collectstatic --noinput && python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - ./pr:/app
      - ./pr/static:/app/static
    ports:
      - "8000:8000"
    environment:
      - MYSQL_DATABASE=dj1
      - MYSQL_USER=ab_usr
      - MYSQL_PASSWORD=mypass
    depends_on:
      - dj1_mariadb
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

完整报错信息

my@host:~/dj1$ docker-compose run dj1_web python3 manage.py inspectdb
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
    self.connection = self.get_new_connection(conn_params)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
    connection = Database.connect(**conn_params)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
    return Connection(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
    super().__init__(*args, **kwargs2)
MySQLdb.OperationalError: (2002, "Can't connect to server on 'dj1_mariadb' (115)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/app/manage.py", line 22, in <module>
    main()
  File "/app/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 413, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 459, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/inspectdb.py", line 47, in handle
    for line in self.handle_inspection(options):
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/inspectdb.py", line 60, in handle_inspection
    with connection.cursor() as cursor:
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 320, in cursor
    return self._cursor()
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 296, in _cursor
    self.ensure_connection()
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 278, in ensure_connection
    with self.wrap_database_errors:
  File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
    self.connection = self.get_new_connection(conn_params)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
    connection = Database.connect(**conn_params)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
    return Connection(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
    super().__init__(*args, **kwargs2)
django.db.utils.OperationalError: (2002, "Can't connect to server on 'dj1_mariadb' (115)")

排查与解决步骤

1. 等待MariaDB完全就绪

depends_on仅保证容器启动顺序,不代表数据库服务已初始化完成。可执行以下命令验证网络连通性,再等待3-5分钟让MariaDB完成启动:

docker-compose run dj1_web ping dj1_mariadb

也可使用wait-for-it脚本强制等待数据库端口就绪:
修改docker-compose.yml中dj1_web的command:

command: >
  sh -c "apt-get update && apt-get install -y wait-for-it && wait-for-it dj1_mariadb:3306 -t 60 && python3 manage.py collectstatic --noinput && python3 manage.py runserver 0.0.0.0:8000"

2. 检查数据库用户访问权限

MariaDB默认创建的用户可能仅允许localhost访问,需确保ab_usr可从任意主机连接:
进入MariaDB容器:

docker exec -it dj1_mariadb mysql -u root -pmyrpass

执行SQL授权:

GRANT ALL PRIVILEGES ON dj1.* TO 'ab_usr'@'%';
FLUSH PRIVILEGES;

3. 验证环境变量传递

进入Django容器检查环境变量是否正确:

docker exec -it dj1_web env | grep MYSQL

确认MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD与docker-compose.yml配置一致。

4. 确认目标数据库存在

在MariaDB中检查dj1数据库是否存在:

SHOW DATABASES;

若不存在,手动创建:

CREATE DATABASE dj1;

5. 重置数据卷(可选)

如果之前的MariaDB数据卷存在损坏,删除后重新初始化:

docker-compose down -v
docker-compose up -d

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:08:09