生产部署Django必须禁用runserver,设DEBUG=False、ALLOWED_HOSTS为真实域名,collectstatic到STATIC_ROOT,用uWSGI/Gunicorn替代并由systemd管理,换PostgreSQL/MySQL数据库,MEDIA_ROOT设绝对路径并配Nginx,确保权限与日志完备。

直接上生产环境跑 python manage.py runserver 是行不通的——它只是开发服务器,不支持并发、没静态文件服务、无进程管理,一上线就崩。
关掉 DEBUG 并配好 ALLOWED_HOSTS
这是部署第一道安全闸。不改这两项,Django 拒绝响应任何请求,且可能泄露敏感路径信息。
-
DEBUG=False必须写死在settings.py里,别用环境变量临时覆盖 -
ALLOWED_HOSTS要填真实访问域名或 IP,比如['example.com', '192.168.1.100'];填['*']仅限调试,Nginx 或 uWSGI 前置后必须收紧 - 如果用 Nginx 反向代理,还要确认
SECURE_PROXY_SSL_HEADER和USE_X_FORWARDED_HOST是否适配(尤其 HTTPS 场景)
静态文件必须 collectstatic 到 STATIC_ROOT
开发时 Django 自动从 STATICFILES_DIRS 找静态资源,但生产环境它只认 STATIC_ROOT 这一个目录。漏这步,CSS/JS 全 404。
- 先在
settings.py明确定义:STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') - 运行
python manage.py collectstatic --noinput,所有 app 的static/和项目级static/都会被拷进staticfiles/ - Nginx 的
location /static/必须指向这个staticfiles/目录,不是源static/ - SQLite 下可忽略,但换 PostgreSQL/MySQL 后,
collectstatic仍要执行——它和数据库无关,只管前端资源
用 uWSGI 或 Gunicorn 替换 runserver
runserver 单线程、无守护、无重启机制,连两个并发请求都扛不住。uWSGI 和 Gunicorn 是实际生产标配。
立即学习“Python免费学习笔记(深入)”;
- 推荐 uWSGI:配置灵活,和 Nginx 配合成熟,命令示例:
uwsgi --ini uwsgi.ini,其中uwsgi.ini至少含socket、chdir、module(如mysite.wsgi:application) - Gunicorn 更轻量,适合容器化部署,启动命令类似:
gunicorn mysite.wsgi:application --bind 127.0.0.1:8001 --workers 3 - 无论选哪个,都得用
systemd或supervisord管理进程,否则终端一关,服务就死 - 注意 Python 版本兼容:Python 3.8 + uWSGI 2.0.14+ 是稳定组合,低于此版本可能报
ModuleNotFoundError: No module named 'encodings'
数据库和 media 文件不能靠本地路径硬编码
SQLite 文件(db.sqlite3)和用户上传的 media/ 目录,一旦部署到多机或容器环境,路径就不可靠。
- SQLite 仅限开发或极小流量场景;生产务必换 PostgreSQL 或 MySQL,并把连接参数移到环境变量中(用
os.getenv('DB_URL')读取) -
MEDIA_ROOT要设为绝对路径,比如/var/www/mysite/media,并确保 uWSGI/Gunicorn 进程有写权限 - Nginx 需显式配置
location /media/指向该路径,否则用户上传的图片无法访问 - 如果用云存储(如 OSS/S3),就别碰本地
MEDIA_ROOT,直接集成django-storages+ 对应后端
最常被跳过的其实是权限和日志——uWSGI 进程用户得对 STATIC_ROOT、MEDIA_ROOT、db.sqlite3(如果还在用)都有读写权,且 uwsgi.log 或 gunicorn.error.log 得设好路径并轮转,否则出问题时连错在哪都不知道。


















