Dockerfile构建Django镜像,docker-compose.yml编排Django、MySQL、Nginx等多容器启动顺序与网络;二者必须配合,缺一不可。

直接上结论:Dockerfile 负责构建单个 Django 应用镜像,docker-compose.yml 负责协调 Django、数据库(如 MySQL)、Nginx 等多个容器的启动顺序、网络和挂载——两者必须配合使用,缺一不可。
为什么 Dockerfile 里不能直接写 python manage.py runserver
开发模式的 runserver 不适合生产环境:无并发处理能力、无静态文件服务、不支持进程守护。更重要的是,在容器构建阶段(docker build),数据库服务根本没启动,manage.py 会因连接不到 DB 直接失败。
- 生产推荐用
gunicorn或uWSGI,例如:gunicorn --bind :8000 --workers=4 django_app.wsgi:application -
CMD或ENTRYPOINT应放在 Dockerfile 末尾,但更推荐把启动命令挪到docker-compose.yml的command字段中,方便调试和覆盖 - 若硬要在 Dockerfile 写 CMD,务必确保
settings.py中的数据库配置使用环境变量(如os.environ.get('DB_HOST', 'db')),而非写死localhost
docker-compose.yml 中 depends_on 并不保证服务“就绪”
depends_on 只控制容器启动顺序,不等待目标服务(比如 MySQL)真正监听端口或完成初始化。Django 容器启动时可能立刻尝试连 DB,而 MySQL 还在初始化表结构,结果报 OperationalError: (2003, "Can't connect to MySQL server")。
- 解决方案是加启动重试逻辑:在
command中包装一层 bash 脚本,用nc -z db 3306或mysqladmin ping -h db -u root -p$MYSQL_ROOT_PASSWORD --silent循环检测 - 或者用官方推荐的
wait-for-it.sh工具(需提前 COPY 进镜像) -
healthcheck配置可辅助判断,但需配合自定义脚本,单纯靠depends_on不可靠
Django 静态文件收集必须在容器内执行,且路径要对齐
python manage.py collectstatic --no-input 必须在运行时(不是构建时)执行,因为 STATIC_ROOT 挂载进来的 collected_static 卷是空的;同时 Nginx 容器需要能读取这个目录,否则 404。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
立即学习“Python免费学习笔记(深入)”;
- 确保
docker-compose.yml中 Django 服务的volumes挂载了宿主机某目录(如./static-volume:/code/collected_static) - Nginx 服务也必须挂载同一目录(如
static-volume:/code/collected_static),并配置location /static/指向该路径 -
collectstatic命令应放在command开头,例如:bash -c "python manage.py collectstatic --no-input && python manage.py migrate && gunicorn ..." - 别忘了在
settings.py中设置STATIC_ROOT = '/code/collected_static',和挂载路径一致
Windows 下路径和换行符容易引发构建失败
Windows 默认用 CRLF 换行,而 Linux 容器只认 LF;另外 ADD . /code/ 在 Windows 上若项目路径含中文或空格,也可能导致 COPY 失败。
- 用 VS Code 或 Notepad++ 将
Dockerfile和docker-compose.yml保存为 UTF-8 无 BOM + LF 格式 - Git 用户建议全局设置:
git config --global core.autocrlf input - 避免在项目路径中使用中文、空格或特殊符号;推荐把项目放在
C:\projects\my-django-app这类纯英文路径下 - 如果用 WSL2,优先在 WSL 内执行
docker-compose up,避开 Windows 文件系统层的兼容问题
最常被忽略的一点:Django 容器里 ALLOWED_HOSTS 必须包含服务名(如 'web' 或 'app'),而不是 'localhost' 或 '127.0.0.1'——因为容器间通信走的是内部网络别名,不是回环地址。

















