Django Docker 部署七条最佳实践
用 Docker 部署 Django 的七条军规:选对项目骨架、环境变量配置、健康检查、静态与媒体文件处理、数据库迁移策略、Celery 异步任务与可扩展的日志方案。
直接回答:生产级 Django 容器化部署远不止写个 Dockerfile——需要处理好骨架选型、配置外置、健康检查、静态文件、迁移策略、异步任务与日志采集七个关键环节,本文逐条给出可落地做法。
1. 选对项目骨架
从零手写 Docker 配置容易踩坑,成熟的 Django Docker 模板(官方示例或社区 boilerplate)已经把多阶段构建、非 root 运行、依赖分层缓存做好。评估骨架时看三点:镜像体积(是否 slim/alpine 变体)、构建速度(依赖层与应用层是否分离)、安全基线(是否非 root 运行)。
2. 配置一律走环境变量
import os
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
DEBUG = os.environ.get("DEBUG", "0") == "1"
import dj_database_url # 需安装 dj-database-url
DATABASES = {"default": dj_database_url.parse(os.environ["DATABASE_URL"])}
密钥、数据库连接、开关全部外置——同一份镜像跑遍 dev/staging/prod,密钥绝不进镜像层。Docker Compose 用 env_file,Kubernetes 用 Secret。
3. 实现可靠的健康检查
容器编排系统需要知道应用"活着且能服务":
# urls.py
path("health/", lambda r: JsonResponse({"status": "ok"}))
HEALTHCHECK写在 Dockerfile 或 compose 里;- 探针分两层:
liveness(进程活着)与readiness(能接流量,含数据库连通性); - 健康检查要轻,别把全链路压测塞进探针。
4. 静态与媒体文件的正确姿势
容器内 collectstatic 收集到卷或对象存储;静态文件交给 WhiteNoise(简单场景)或 CDN+对象存储(生产推荐);用户上传的媒体文件绝不放容器文件系统——容器是易失的,用 S3 兼容对象存储。
5. 数据库迁移策略
migrate 不该由每个启动的容器抢着跑。稳妥做法:
- 用独立 K8s Job 或发布流水线步骤执行迁移;每个 Pod 各自的 init 容器不能保证全局只执行一次;
- 迁移必须向后兼容(先加字段、发版、再删字段的两步走),支持滚动发布;
- 失败要有告警——迁移挂住而流量已切入是最痛的发布事故。
6. 异步任务配 Celery
Web 容器只管接请求,慢活交给 Celery worker 容器:
- worker 与 Web 用同一镜像、不同启动命令,镜像版本天然一致;
- broker 用 Redis/RabbitMQ,单独容器或托管服务;
- worker 也要健康检查与资源限制,任务堆积要有监控。
7. 可扩展的日志策略
容器时代日志铁律:写 stdout/stderr,不写文件。
LOGGING = {
"version": 1,
"handlers": {"console": {"class": "logging.StreamHandler"}},
"root": {"handlers": ["console"], "level": "INFO"},
}
日志采集交给平台层:采集器从容器 stdout 抓取,统一聚合、检索、告警。结构化 JSON 输出让日志可被机器高效消费。
接入观测云时,可按 DataKit 日志采集指南配置容器日志采集。给 Web 和 Celery worker 的日志分别标记服务名,并记录发布版本和任务 ID;用一次失败任务检查能否从 worker 日志找到异常,避免只收到了 Web 请求日志。
常见问题(FAQ)
Q:Gunicorn 进程数怎么定?
A:经典公式 (2 × CPU) + 1 起步,容器里别忘了把 CPU limit 作为基数;再按本项目压测的内存与并发调整。
Q:静态文件用 WhiteNoise 还是 Nginx?
A:单容器简单部署 WhiteNoise 最省事;多副本生产部署建议对象存储 + CDN,Nginx 反代只负责动态流量。
Q:迁移和服务启动的顺序怎么保证?
A:编排层解决:发布流程等待独立 Job 成功再更新 Deployment;Compose 用一次性迁移服务与 service_completed_successfully 依赖条件,单独 depends_on 不保证完成。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。