不能直接用 python manage.py runserver 上生产,因为它是单进程、无超时、不处理静态文件、不防攻击、默认绑定本地地址的调试服务器;生产环境需用 gunicorn 托管 django、nginx 反向代理并处理静态文件与 ssl、docker 固化环境。

为什么不能直接用 python manage.py runserver 上生产
因为 runserver 是纯开发用的调试服务器:单进程、无超时控制、不处理静态文件、不防 DDoS、默认绑定 127.0.0.1:8000,连外网请求都收不到。线上跑它等于裸奔。
生产必须拆开职责:Django 只管业务逻辑(用 Gunicorn 托管),Nginx 负责反向代理、静态文件服务、SSL 终止、连接池管理。Docker 则把整套环境打包固化,避免“在我机器上能跑”问题。
怎么写最小可用的 Dockerfile(别抄网上全量版)
核心是分层缓存 + 安全基础镜像。用 python:3.11-slim-bookworm 比 alpine 更省心(glibc 兼容性好,少踩 C 扩展编译坑)。
- 不要在
RUN pip install前复制整个项目 —— 改成先COPY requirements.txt,再pip install,利用 Docker 层缓存 -
USER 1001必须加,避免以 root 运行 Gunicorn(Django 官方安全建议) -
EXPOSE 8000只是声明,实际端口由docker run -p或 Docker Compose 控制 - 静态文件别在容器里 collectstatic —— 推荐构建时执行,或挂载 volume 外部生成
FROM python:3.11-slim-bookworm WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN python manage.py collectstatic --noinput USER 1001 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "myproject.wsgi:application"]
Gunicorn 启动参数哪些真有用,哪些纯属炫技
线上真正影响稳定性的就几个参数,其余大半是调优陷阱(比如 --preload 在某些 ORM 场景下会导致数据库连接复用错误)。
-
--bind 0.0.0.0:8000:必须绑定0.0.0.0,否则 Nginx 连不上容器内网 -
--workers:通常设为(2 × CPU 核数) + 1,但小项目直接4足够;别盲目堆到 16+ -
--timeout 120:防止长任务卡死 worker,比 Django 的TIMEOUT更底层 -
--keep-alive 5:Nginx 默认 keepalive_timeout=65,这里设小点(如 5)可减少空闲连接堆积 - 去掉
--preload:Django 项目用了数据库连接池或 Celery 时,preload 会提前加载模块,导致连接被 fork 复制出错
Nginx 配置里最容易漏掉的三处关键项
很多教程只贴个反向代理 skeleton,结果上线后 502、静态文件 404、HTTPS 重定向死循环全来了。
-
proxy_pass http://web:8000;中的web是 Docker Compose 里 service 名,不是 localhost —— 容器间通信走内部 DNS - 静态文件必须显式配置
location /static/,且alias结尾要带斜杠:alias /app/staticfiles/;(注意末尾 /) - HTTPS 下必须加
proxy_set_header X-Forwarded-Proto $scheme;,否则 Django 的request.is_secure()永远返回 False,Admin 登录页跳转 HTTP
复杂点在于 Nginx 和 Gunicorn 的超时要对齐:Gunicorn --timeout 120 → Nginx proxy_read_timeout 120,不然用户上传大文件时,Nginx 先断连,报 504。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











