凌晨两点,老周盯着屏幕上那个刺眼的500错误,这是他连续第三晚在调试Django的部署问题,他是一位刚转行的爬虫工程师,以为会写Python就能搞定网站,结果被Nginx、Gunicorn、静态文件、数据库连接这些陌生的词折腾到怀疑人生,如果你也是他这样——懂点Python基础,想用Django做点正经项目,却被“上线”二字卡住,那么这篇指南是为你准备的。
适用人群:有Python基础、能用Django写过本地小项目、但从未将网站部署到公网服务器上的开发者,如果你连虚拟环境都不熟,建议先补课再来看,这篇文章的每一步,都默认你已经会写views和models了。
第一步:选服务器,别在第一步就选错配置
服务器是地基,不要买最低配的1核1G部署生产环境,Django自带的管理后台加一个简单的数据库查询就能把内存吃满,我的建议是:2核4G起步,带宽按需选择,云服务商选阿里云、腾讯云或者AWS都行,重点是操作系统选 Ubuntu 22.04 LTS,因为它的Python版本和依赖库支持最省心。
从零到上线,用Django搭一个能扛住百万级流量的网站,其实只需这七步
配置要点:登录服务器后,立刻执行 sudo apt update && sudo apt upgrade,然后创建一个非root用户,禁用root密码登录,改SSH端口为2222(减少暴力破解),这一步很多人跳过,等被扫了端口才后悔。
第二步:装环境,一个坑一个坑地排
不要用系统自带的Python3.10,直接用 apt install python3.11,为什么?因为Django 4.2+和最新版Gunicorn在3.10上有隐性行为差异,尤其是URL路由的中文编码问题。
踩坑提醒:安装MySQL或PostgreSQL时,千万别默认装成MariaDB就当PostgreSQL用,两者的连接驱动完全不同,我推荐用PostgreSQL 14+,因为它的JSONField支持比MySQL好太多,装完后设置密码时,注意避开特殊字符如 @ # $,很多连接报错都是因为密码里的特殊字符被shell转义了。
第三步:项目结构,别把静态文件放错地方
在服务器上建 /var/www/myproject 目录,把你的项目代码拉进去,重点来了:Django的settings.py里,DEBUG必须设为False,ALLOWED_HOSTS 要写上你的域名或服务器IP,否则上线后你只会看到一个“DisallowedHost”的报错页面。
配置要点:
STATIC_ROOT = '/var/www/myproject/staticfiles/'MEDIA_ROOT = '/var/www/myproject/media/'然后运行python manage.py collectstatic,这一步会把你所有app的静态文件收集到一起,否则Nginx找不到你的CSS和JS。
第四步:Gunicorn——让Django跑起来
直接用 gunicorn myproject.wsgi:application --bind 127.0.0.1:8000 --workers 3 测试一下,如果报错说找不到模块,检查你的虚拟环境是否激活,且 cd 进了项目目录。
踩坑提醒:workers 数量不是越多越好,公式是CPU核心数*2+1,我的2核服务器用5个worker,多了反而因为线程切换导致性能下降,把Gunicorn注册成systemd服务,这样服务器重启后能自动拉起。
第五步:Nginx反向代理——把80端口接住
这是最容易出错的一步,很多人直接抄教程里的Nginx配置就去改,结果忘了写 proxy_set_header Host $host;,导致Django里的 request.get_host() 拿到的永远是 0.0.1,所有需要绝对URL的功能(比如邮件链接、分页)全部失效。
核心配置块:
server {
listen 80;
server_name yourdomain.com;
location /static/ {
alias /var/www/myproject/staticfiles/;
}
location /media/ {
alias /var/www/myproject/media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
改完配置执行 nginx -t 测试语法,再 systemctl reload nginx。这里有个反直觉的坑:alias 后面的路径结尾必须带斜杠 ,不加就会多出一层目录,静态文件全404。
第六步:域名与HTTPS——让浏览器信任你
买好域名后,去DNS解析商那里加一条A记录,指向你的服务器IP,别用CNAME解析到别人的服务器上,除非你知道自己在干什么。
HTTPS用 Let's Encrypt 免费证书,安装 certbot 后执行 certbot --nginx -d yourdomain.com,它会自动修改Nginx配置并启用强制跳转。
踩坑提醒:证书续期是个坑,默认的续期服务是用cron实现的,但很多云服务器上cron不会自动启动,检查 /etc/cron.d/certbot 是否存在,并手动执行 systemctl enable cron,不然三个月后你的网站突然显示“不安全”,然后流量跌一半。
第七步:上线前最后的健康检查
部署完别急着关终端,跑这几个命令:
python manage.py check --deploy——它会列出一堆安全警告,SECURE_SSL_REDIRECT没配置,这个要去settings.py里加上。tail -f /var/log/nginx/error.log——盯着日志访问一下网站每个页面,尤其注意有没有500错误。- 测试数据库迁移:
python manage.py migrate --plan,确保没有未执行的迁移。
最后一个致命坑:如果你的项目用了 django-tinymce 或者其他富文本编辑器,上传图片功能会报错,原因是CSRF验证在HTTPS下会校验Referer头,而你的Nginx没转发 X-Forwarded-Proto,在Nginx的location块里加一句 proxy_set_header X-Forwarded-Proto $scheme; 就解决了。



发表评论