最稳妥的django+mysql入门方式是docker-compose,但需避开三个硬性坑:mysql 8默认认证插件不兼容(须设--default-authentication-plugin=mysql_native_password)、django的host必须写服务名“mysql”而非localhost、容器启动顺序无保障需用healthcheck+service_healthy或entrypoint脚本等待db就绪。

直接用 docker-compose 启动 Django + MySQL 是最稳妥的入门方式,但必须避开三个硬性坑:MySQL 8 默认认证插件不兼容、Django 的 HOST 必须写服务名而非 localhost、容器启动顺序没保障时数据库连接会报错。
MySQL 8 容器必须显式指定认证插件
MySQL 8.0+ 默认使用 caching_sha2_password,而 mysqlclient 和多数 Python 驱动只支持 mysql_native_password。不改就会卡在 django.db.utils.OperationalError: (2059, "Authentication plugin 'caching_sha2_password' cannot be loaded")。
解决方法是在 docker-compose.yml 的 mysql 服务里加 command 参数:
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password --mysqlx=0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: hrun
MYSQL_USER: dev
MYSQL_PASSWORD: 123456
volumes:
- ./db:/var/lib/mysql
- 不能只靠
environment变量解决认证问题 -
--mysqlx=0是可选的,但建议加上,避免 X Protocol 端口干扰 - 如果用的是
mysql:5.7,这一步可跳过
Django settings.py 中的 HOST 必须匹配 service 名称
Docker 内部网络靠服务名做 DNS 解析,localhost 或 127.0.0.1 指向容器自己,不是数据库容器。
确保 settings.py 里这样写:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'hrun',
'USER': 'dev',
'PASSWORD': '123456',
'HOST': 'mysql', # ← 必须和 docker-compose.yml 里 service 名一致
'PORT': '3306',
}
}
- 哪怕
docker-compose.yml中container_name设为yy_mysql,HOST仍应填mysql(只要 service 名是mysql) - 检查
docker-compose.yml顶层services:下的 key 名,就是 DNS 名 - 运行
docker-compose exec web ping mysql能通,才说明网络连通
web 服务启动前必须等 MySQL 就绪
depends_on 只控制启动顺序,不等 MySQL 进程真正 ready,Django 容器常因连接拒绝崩溃重启。
两种轻量级解法:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 用
healthcheck+condition: service_healthy(推荐) - 在 Django 容器内加启动脚本,循环检测
mysql端口是否响应
示例 healthcheck 片段:
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password --mysqlx=0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123456"]
timeout: 20s
retries: 10
<p>web:
build: .
depends_on:
mysql:
condition: service_healthy</p>
注意:test 命令里的密码是明文,仅限开发环境;生产环境应通过 .my.cnf 或环境变量传参。
Dockerfile 中不要提前执行 migrate 或 runserver
很多新手把 CMD ["python", "manage.py", "migrate"] 写进 Dockerfile,结果镜像构建时就报数据库连接失败 —— 因为此时 MySQL 根本没启动。
正确做法是:
-
Dockerfile只负责安装依赖、复制代码、设工作目录 -
migrate放到容器启动时执行,比如用entrypoint.sh -
runserver仅用于开发;生产用gunicorn或uwsgi,且需配合collectstatic
一个最小可用 entrypoint.sh:
#!/bin/sh # 等待 DB 可用(简单版) while ! nc -z mysql 3306; do sleep 1 done # 执行迁移 python manage.py migrate # 启动服务 exec "$@"
然后在 docker-compose.yml 中声明:entrypoint: ./entrypoint.sh,command 留给真正的启动命令。
最易被忽略的一点:所有容器间通信都走 Docker 自建网络,HOST 写错、healthcheck 缺失、MySQL 认证插件不设,三者任一出问题都会导致“连得上但连不通”,排查时优先查 docker-compose logs mysql 和 docker-compose logs web,而不是翻 Django 报错堆栈。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










