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
相关产品推荐
相关产品推荐

