
1. 为什么选择NginxGunicorn部署Django很多刚接触Django开发的朋友在项目上线时都会遇到一个难题为什么本地用python manage.py runserver跑得好好的一到服务器就各种问题其实这个开发服务器就是个玩具根本扛不住真实流量。我在早期项目里吃过亏用开发服务器上线后不到10个并发请求就直接崩溃了。Gunicorn就像是个专业的保镖专门保护Django应用。它用pre-fork模式就是提前准备好多个工作进程来处理请求比开发服务器稳定得多。实测我的个人博客用Gunicorn后即使突然有几百人访问也不会挂掉。而Nginx则是更前线的调度员负责把用户请求合理分配给后端的Gunicorn workers还能顺手处理静态文件、防御恶意请求。这个组合还有个隐藏优势——零成本。不像某些商业方案需要额外付费它们都是开源工具。去年我给客户部署电商系统用这套方案每月省下近千元的服务费。下面我就手把手带你走通整个部署流程连我踩过的坑都会标注出来。2. 部署前的准备工作2.1 云服务器选购避坑指南第一次买云服务器时我被各种配置参数搞得头晕。后来才发现对于刚上线的Django项目腾讯云轻量应用服务器的2核4G配置就够用大概一年300元左右。注意一定要选Ubuntu 22.04 LTS这个长期支持版本稳定性最好。有次我图新鲜用了非LTS版本结果半年后系统停止维护被迫半夜迁移服务器。买完服务器记得做三件事立即设置SSH密钥登录比密码安全得多新建专用用户别用root直接操作开启基础防火墙至少放行80/443端口这里有个血泪教训有次我忘记开防火墙服务器刚启动就被挖矿程序入侵了。具体操作如下# 创建部署专用用户 adduser deployer usermod -aG sudo deployer # 配置SSH密钥本地机器执行 ssh-copy-id deployer你的服务器IP2.2 项目本地调优技巧上传代码前建议先在本地做好这些优化在settings.py中设置DEBUGFalse重要否则会暴露敏感信息用python manage.py check --deploy检查部署安全性生成精确的依赖列表pip freeze requirements.txt我遇到过requirements.txt漏包的情况导致服务器环境装不全依赖。后来发现用pipenv管理更可靠# 使用pipenv生成确定性的依赖文件 pipenv lock -r requirements.txt3. 服务器环境搭建实战3.1 必装的系统组件别急着装Python环境先把这些基础包装好sudo apt update sudo apt install -y python3-pip python3-dev libpq-dev nginx curl git特别注意libpq-dev这个包如果你用PostgreSQL数据库Django官方推荐没装它会导致psycopg2安装失败。曾经有次部署卡了2小时就是因为漏了这个包。3.2 Python环境隔离方案我强烈推荐用virtualenvwrapper管理虚拟环境比直接装virtualenv方便多了sudo pip3 install virtualenvwrapper然后在~/.bashrc末尾添加export WORKON_HOME$HOME/.venvs export VIRTUALENVWRAPPER_PYTHON/usr/bin/python3 source /usr/local/bin/virtualenvwrapper.sh加载配置后创建专属环境source ~/.bashrc mkvirtualenv django_deploy --python/usr/bin/python3小技巧用workon django_deploy可以快速切换环境比手动激活方便多了4. 项目部署核心步骤4.1 代码上传的两种姿势方法一Git克隆推荐git clone https://github.com/yourname/project.git cd project方法二SFTP上传如果用FileZilla等工具上传记得检查文件权限sudo chown -R deployer:deployer /path/to/project我更喜欢用Git因为可以方便地回滚版本。有次更新出问题直接用git reset --hard就恢复了。4.2 依赖安装的避坑技巧在虚拟环境中安装依赖时加个--no-cache-dir能避免很多奇怪问题workon django_deploy pip install --no-cache-dir -r requirements.txt如果遇到编译错误可能需要额外安装系统库。比如Pillow包需要sudo apt install -y libjpeg-dev zlib1g-dev4.3 数据库配置实战以PostgreSQL为例先安装数据库服务sudo apt install -y postgresql postgresql-contrib然后创建数据库用户别用postgres超级用户CREATE DATABASE djangodb; CREATE USER djangouser WITH PASSWORD strongpassword; ALTER ROLE djangouser SET client_encoding TO utf8; GRANT ALL PRIVILEGES ON DATABASE djangodb TO djangouser;在Django的settings.py中配置DATABASES { default: { ENGINE: django.db.backends.postgresql, NAME: djangodb, USER: djangouser, PASSWORD: strongpassword, HOST: localhost, PORT: , } }重要记得把密码放在环境变量里别直接写在代码中5. Gunicorn配置详解5.1 基础安装与测试先安装Gunicornpip install gunicorn简单测试是否正常工作gunicorn --bind 0.0.0.0:8000 project.wsgi访问服务器IP:8000应该能看到你的网站。但这样运行会占用终端我们需要更稳定的方案。5.2 系统服务化配置创建/etc/systemd/system/gunicorn.service[Unit] DescriptionGunicorn for Django Afternetwork.target [Service] Userdeployer Groupwww-data WorkingDirectory/home/deployer/project ExecStart/home/deployer/.venvs/django_deploy/bin/gunicorn \ --workers 3 \ --bind unix:/run/gunicorn.sock \ project.wsgi:application [Install] WantedBymulti-user.target关键参数说明workers数量公式CPU核心数 × 2 1用Unix socket比TCP端口更高效用户权限要严格限制启动服务sudo systemctl start gunicorn sudo systemctl enable gunicorn检查状态sudo systemctl status gunicorn6. Nginx终极配置指南6.1 基础反向代理配置在/etc/nginx/sites-available/project中添加server { listen 80; server_name yourdomain.com; location /static/ { alias /home/deployer/project/static/; expires 30d; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } }启用配置sudo ln -s /etc/nginx/sites-available/project /etc/nginx/sites-enabled sudo nginx -t # 测试配置 sudo systemctl restart nginx6.2 性能优化技巧在nginx的http块中加入这些参数http { # 启用gzip压缩 gzip on; gzip_types text/plain text/css application/json application/javascript; # 优化文件传输 sendfile on; tcp_nopush on; keepalive_timeout 65; }这些配置能让静态文件加载速度提升30%以上特别对CSS/JS文件效果明显。7. 安全加固必做事项7.1 防火墙配置只开放必要端口sudo ufw allow ssh sudo ufw allow http sudo ufw allow https sudo ufw enable7.2 HTTPS免费方案用Lets Encrypt免费证书sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com自动续期测试sudo certbot renew --dry-run建议设置crontab自动续期0 3 * * * /usr/bin/certbot renew --quiet8. 故障排查手册8.1 502 Bad Gateway可能原因Gunicorn没运行Socket文件权限错误Nginx配置错误排查步骤# 检查Gunicorn状态 sudo journalctl -u gunicorn --no-pager -n 50 # 检查socket权限 ls -la /run/gunicorn.sock8.2 静态文件404解决方法确认执行了python manage.py collectstatic检查Nginx配置中的路径是否正确确保static目录有读取权限sudo chmod -R 755 /home/deployer/project/static9. 高级优化方案9.1 数据库连接池安装django-db-geventpoolpip install django-db-geventpool修改settings.pyDATABASES { default: { ENGINE: django_db_geventpool.backends.postgresql_psycopg2, MAX_CONNS: 20, # 连接池大小 ...其他原有配置... } }9.2 异步任务处理对于耗时操作建议用Celery# tasks.py app.task def send_email(): # 发送邮件逻辑 # 视图调用 send_email.delay()启动Celery workercelery -A project worker -l info10. 自动化部署技巧用Fabric实现一键部署# fabfile.py from fabric import task task def deploy(c): c.run(git pull origin main) c.run(workon django_deploy pip install -r requirements.txt) c.run(python manage.py migrate) c.run(python manage.py collectstatic --noinput) c.sudo(systemctl restart gunicorn) c.sudo(systemctl reload nginx)执行部署fab deploy