Docker容器化部署Django全栈应用的核心是docker-compose.yml中服务间网络打通、环境变量注入准确、ALLOWED_HOSTS和DEBUG动态覆盖;DB_HOST必须设为service名(如db)而非localhost,DEBUG与ALLOWED_HOSTS须通过环境变量配置,collectstatic需在构建或启动时执行,且STATIC_ROOT路径须与Nginx配置严格对齐。

直接上结论:Docker容器化部署Django全栈应用,核心不是“能不能跑”,而是docker-compose.yml里服务间网络打通、环境变量注入是否准确、以及Django的ALLOWED_HOSTS和DEBUG在容器中是否被正确覆盖——这三点出错,90%的“启动成功但访问404/502/Connection refused”问题就来了。
docker-compose.yml 中 service 依赖顺序和 network_mode 写错会直接导致 Django 连不上数据库
Django容器启动时如果DB_HOST指向错误(比如写成localhost或127.0.0.1),它连的其实是自己容器内部的回环地址,而不是PostgreSQL容器。Docker默认为每个service分配独立网络命名空间,容器间通信必须用service name作为主机名。
- PostgreSQL服务名定义为
db,Django里DB_HOST就必须设为db,不能是localhost - 确保
depends_on只控制启动顺序,不保证服务已就绪;加healthcheck或用wait-for-it.sh脚本更稳妥 - 别用
network_mode: "host"——它会让所有容器共享宿主机网络,破坏隔离性,且在Mac/Windows上行为不一致
Django 的 DEBUG=False 和 ALLOWED_HOSTS 必须通过环境变量动态注入
硬编码DEBUG = False在settings.py里,容器一启就炸:Django拒绝响应任何非ALLOWED_HOSTS的请求,而默认值['localhost', '127.0.0.1']在容器里完全无效。
- 用
django-environ读取.env或环境变量:DEBUG = env.bool('DEBUG', default=False) -
ALLOWED_HOSTS必须包含Nginx反向代理的host(如'nginx')、前端域名(如'myapp.com'),或通配'*'(仅限开发) - 在
docker-compose.yml中显式传入:environment: - DEBUG=False - ALLOWED_HOSTS=nginx,backend
静态文件收集(collectstatic)必须在构建时或启动时执行,不能靠runserver
开发用python manage.py runserver能自动serve static,但生产环境Nginx不认Django的static路径。如果Docker镜像里没运行collectstatic,Nginx返回404就纯属正常。
立即学习“Python免费学习笔记(深入)”;
- 在
Dockerfile的COPY . .之后加:RUN python manage.py collectstatic --noinput - 或者把static目录挂载为volume,让Nginx直接读宿主机路径(需同步权限和路径)
- 注意:
STATIC_ROOT必须指向Nginx能访问的绝对路径,比如/app/staticfiles,且Nginx配置里alias要严格匹配
最常被忽略的一点:Docker内Python进程默认以root运行,但Django官方强烈建议用非root用户启动。一旦你加了user: "1001:1001"却忘了给/app目录赋权,collectstatic或migrate就会因权限失败静默退出——日志里只显示“exited with code 0”,根本看不出哪里错了。


















