Docker部署Django+MySQL遇连接错误,求启动配置与命令指导
问题概述
在Debian环境下将Django项目与MySQL数据库分别部署到独立Docker容器时,出现连接错误:Lost connection to MySQL server during query ([Errno 104] Connection reset by peer)。此外,Django数据库用户需创建触发器,必须确保MySQL启用log_bin_trust_function_creators=1配置。当前使用settings/.env文件存储数据库凭证,该文件同时用于初始化数据库容器。
现有配置
docker-compose.yml
version: '3.3' services: db: image: mysql:8.0.29 container_name: db_mysql_container environment: MYSQL_DATABASE: $DB_NAME MYSQL_USER: $DB_USER MYSQL_PASSWORD: $DB_PASSWORD MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD command: ["--log_bin_trust_function_creators=1"] ports: - '3306:3306' expose: - '3306' api: build: . container_name: django_container command: bash -c "pip install -q -r requirements.txt && python manage.py migrate && python manage.py runserver 0.0.0.0:8000" volumes: - .:/app ports: - '8000:8000' depends_on: - db
Dockerfile
# syntax=docker/dockerfile:1 FROM python:3.9.14-buster ENV PYTHONUNBUFFERED=1 RUN mkdir /app WORKDIR /app COPY requirements.txt /app/ RUN pip install -r requirements.txt ADD . /app/
关键修改建议
1. 修复Django数据库连接配置
在Django的settings.py中,数据库HOST需指向Docker Compose的服务名db(而非localhost),同时从.env文件加载凭证:
# settings.py import os from dotenv import load_dotenv # 加载settings目录下的.env文件 load_dotenv(os.path.join(os.path.dirname(__file__), '.env')) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': os.getenv('DB_NAME'), 'USER': os.getenv('DB_USER'), 'PASSWORD': os.getenv('DB_PASSWORD'), 'HOST': 'db', # 对应docker-compose中的db服务名 'PORT': '3306', } }
确保python-dotenv已添加到requirements.txt中。
2. 确保数据库就绪后再执行Django操作
depends_on仅保证容器启动顺序,不确保MySQL服务完全就绪。需在Django容器启动脚本中添加等待逻辑:
修改docker-compose.yml中api服务的command:
command: bash -c "apt-get update && apt-get install -y netcat-traditional && while ! nc -z db 3306; do sleep 1; echo 'Waiting for MySQL...'; done && pip install -q -r requirements.txt && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
3. 正确加载.env文件
Docker Compose默认读取项目根目录的.env文件,若你的.env在settings/目录下,需在docker-compose.yml开头指定路径:
version: '3.3' env_file: - ./settings/.env # 指定.env文件路径 services: # ... 原有服务配置
4. 验证MySQL的log_bin_trust_function_creators配置
当前db服务的command已添加--log_bin_trust_function_creators=1,可进入容器验证:
docker exec -it db_mysql_container mysql -u root -p # 输入root密码后执行 SHOW VARIABLES LIKE 'log_bin_trust_function_creators';
若值为ON则配置生效。
操作步骤
1. 准备.env文件
在settings/.env中填写数据库凭证:
DB_NAME=your_db_name DB_USER=your_db_user DB_PASSWORD=your_db_password DB_ROOT_PASSWORD=your_root_password
2. 整理依赖清单
确保requirements.txt包含必要依赖:
# requirements.txt django>=3.2 mysqlclient>=2.1.0 python-dotenv>=1.0.0 # 其他项目依赖...
3. 构建并启动所有容器
# 构建镜像并前台启动容器 docker-compose up --build # 后台运行加-d参数:docker-compose up --build -d
4. 单独启动数据库容器
# 仅启动db服务并后台运行 docker-compose up -d db # 查看数据库容器日志,验证启动状态 docker-compose logs db # 进入数据库容器,直接连接数据库 docker exec -it db_mysql_container mysql -u $DB_USER -p$DB_PASSWORD $DB_NAME
5. 手动执行迁移(可选)
若自动迁移失败,可进入Django容器手动执行:
docker exec -it django_container bash # 进入容器后执行迁移命令 python manage.py migrate
常见问题排查
- 连接错误:检查DATABASES中的HOST是否为
db,可通过docker exec django_container ping db测试容器间网络连通性 - 触发器权限问题:确保MySQL用户拥有创建触发器的权限,可在数据库中执行:
GRANT TRIGGER ON your_db_name.* TO 'your_db_user'@'%'; FLUSH PRIVILEGES;
内容的提问来源于stack exchange,提问作者BenjaminFB

