新手在云服务器上从零部署 Django 网站是一个经典但需谨慎的流程。下面是一份清晰、安全、可复现、适合新手的完整指南(以 Ubuntu 22.04 + Nginx + Gunicorn + PostgreSQL + Let’s Encrypt 为例),已避开常见坑点(如权限错误、环境隔离缺失、HTTP/HTTPS 混淆等)。
✅ 前提:你已有一台云服务器(如阿里云/腾讯云/华为云/Vultr/DigitalOcean),操作系统为 Ubuntu 22.04 LTS,并能通过 SSH 登录(建议使用密钥登录)。
🌟 一、准备工作(服务器初始化)
# 1. 更新系统(首次登录后必做)
sudo apt update && sudo apt upgrade -y
# 2. 创建专用部署用户(⚠️ 不要用 root 部署!)
sudo adduser deploy
sudo usermod -aG sudo deploy
# 切换到新用户(后续所有操作在此用户下进行)
su - deploy
# 3. 安装基础依赖
sudo apt install -y python3-pip python3-venv python3-dev build-essential
libpq-dev nginx curl git supervisor
💡 提示:
deploy用户拥有 sudo 权限,但日常操作不加sudo;仅安装/配置系统服务时才用sudo。
🐍 二、准备 Django 项目(本地开发 → 上传)
✅ 本地开发建议(确保项目可运行):
- 使用
django-admin startproject mysite .(注意末尾的.,使 manage.py 在项目根目录) -
settings.py中关键配置:# settings.py(生产环境精简版) import os from pathlib import Path from decouple import config # 推荐用 python-decouple 管理敏感配置 BASE_DIR = Path(__file__).resolve().parent.parent.parent # 根据你的目录结构调整 SECRET_KEY = config('SECRET_KEY') # 从 .env 读取 DEBUG = config('DEBUG', default=False, cast=bool) ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='localhost', cast=lambda v: [s.strip() for s in v.split(',')]) # 数据库(生产用 PostgreSQL) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': config('DB_NAME'), 'USER': config('DB_USER'), 'PASSWORD': config('DB_PASSWORD'), 'HOST': config('DB_HOST', default='localhost'), 'PORT': config('DB_PORT', default='5432'), } } # 静态文件(重要!) STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'staticfiles' # collectstatic 将写入此处 STATICFILES_DIRS = [BASE_DIR / 'static'] # 开发时的静态文件目录 # 媒体文件(如用户上传) MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
✅ 上传项目到服务器:
# 在本地终端(非服务器!)
cd /path/to/your/django-project
git init
git add .
git commit -m "initial commit"
# 推送到 GitHub/GitLab(或直接用 scp/rsync)
git remote add origin https://github.com/yourname/my-django-site.git
git push -u origin main
# 在服务器上(deploy 用户下)克隆
cd ~
git clone https://github.com/yourname/my-django-site.git mysite
cd mysite
✅ 项目结构示例(推荐):
~/mysite/ ├── manage.py ├── mysite/ # Django 项目包(含 settings.py) ├── static/ # 开发用静态文件 ├── media/ # (可选)开发用媒体文件 └── .env # 生产环境配置(⚠️ 不提交到 Git!)
🔐 三、配置生产环境(数据库 + Python 环境)
1️⃣ 安装并配置 PostgreSQL
sudo apt install -y postgresql postgresql-contrib
sudo -u postgres psql -c "CREATE DATABASE mysite_db;"
sudo -u postgres psql -c "CREATE USER mysite_user WITH PASSWORD 'strong_password_here';"
sudo -u postgres psql -c "ALTER ROLE mysite_user SET client_encoding TO 'utf8';"
sudo -u postgres psql -c "ALTER ROLE mysite_user SET default_transaction_isolation TO 'read committed';"
sudo -u postgres psql -c "ALTER ROLE mysite_user SET timezone TO 'UTC';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE mysite_db TO mysite_user;"
2️⃣ 创建 .env 文件(在项目根目录)
cd ~/mysite
cat > .env << 'EOF'
DEBUG=False
SECRET_KEY=your_very_strong_django_secret_key_here
ALLOWED_HOSTS=your-domain.com,www.your-domain.com,123.45.67.89 # 替换为你的域名/IP
DB_NAME=mysite_db
DB_USER=mysite_user
DB_PASSWORD=strong_password_here
DB_HOST=localhost
EOF
🔑 获取 SECRET_KEY:在 Python 中运行
from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())
3️⃣ 创建虚拟环境并安装依赖
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt # 确保 requirements.txt 包含 gunicorn, psycopg2-binary, django, python-decouple 等
4️⃣ 迁移数据库 & 收集静态文件
python manage.py migrate
python manage.py collectstatic --noinput # ⚠️ 必须执行!否则 Nginx 找不到 CSS/JS
✅ 检查:
ls staticfiles/应有admin/,css/,js/等目录。
⚙️ 四、配置 Gunicorn(WSGI 服务器)
创建 Gunicorn 配置文件
# 创建配置目录
sudo mkdir -p /etc/gunicorn.conf.d
sudo nano /etc/gunicorn.conf.d/mysite.conf
内容如下(请按实际路径修改):
[Unit]
Description=Gunicorn daemon for mysite
After=network.target
[Service]
User=deploy
Group=www-data
WorkingDirectory=/home/deploy/mysite
ExecStart=/home/deploy/mysite/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock --bind 127.0.0.1:8000 --timeout 120 --keep-alive 5 --max-requests 1000 --max-requests-jitter 100 --chdir /home/deploy/mysite mysite.wsgi:application
[Install]
WantedBy=multi-user.target
启用并启动 Gunicorn
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
sudo systemctl status gunicorn # ✅ 检查是否 active (running)
✅ 验证 socket:
ls -l /run/gunicorn.sock(应存在且属 deploy:www-data)
🌐 五、配置 Nginx(反向X_X + 静态文件服务)
编辑站点配置
sudo nano /etc/nginx/sites-available/mysite
内容如下(替换 server_name 为你的真实域名):
upstream django_app {
server unix:/run/gunicorn.sock;
}
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# 日志(可选)
access_log /var/log/nginx/mysite_access.log;
error_log /var/log/nginx/mysite_error.log;
# 静态文件(Nginx 直接服务,不走 Django)
location /static/ {
alias /home/deploy/mysite/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# 媒体文件(用户上传)
location /media/ {
alias /home/deploy/mysite/media/;
expires 1y;
}
# 其他请求交给 Gunicorn
location / {
include proxy_params;
proxy_pass http://django_app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
启用站点
sudo ln -sf /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t # ✅ 检查语法是否正确
sudo systemctl restart nginx
sudo systemctl status nginx
✅ 此时访问
http://your-domain.com应看到 Django 默认欢迎页(或你的首页)!
🔐 六、配置 HTTPS(Let’s Encrypt)
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# 按提示输入邮箱,同意协议,选择自动重定向(推荐选 2:Redirect)
✅ 完成后自动配置 HTTPS,并每 90 天自动续期(certbot 已配 systemd timer)。
🧪 七、验证与排错清单(新手必看)
| 现象 | 可能原因 | 快速检查命令 |
|---|---|---|
502 Bad Gateway |
Gunicorn 未运行 / socket 权限错误 | sudo systemctl status gunicorn;ls -l /run/gunicorn.sock |
404 Not Found(CSS/JS) |
collectstatic 未运行 或 Nginx alias 路径错误 |
ls ~/mysite/staticfiles/;检查 Nginx 配置中 alias 路径末尾是否有 / |
Connection refused(127.0.0.1:8000) |
Gunicorn 绑定失败(端口被占/权限) | sudo ss -tulpn | grep :8000;检查 Gunicorn 日志 journalctl -u gunicorn -f |
Internal Server Error |
Django 报错(DEBUG=False 时不显示详情) | 查看 journalctl -u gunicorn -f 和 /var/log/nginx/mysite_error.log |
Forbidden(/static/) |
Nginx 用户无权读取 staticfiles/ |
sudo chown -R deploy:www-data ~/mysite/staticfiles;sudo chmod -R 755 ~/mysite/staticfiles |
📦 八、后续维护小贴士
-
✅ 更新代码:
cd ~/mysite git pull source venv/bin/activate pip install -r requirements.txt python manage.py migrate python manage.py collectstatic --noinput sudo systemctl restart gunicorn -
✅ 查看日志:
journalctl -u gunicorn -f # Gunicorn 实时日志 tail -f /var/log/nginx/mysite_error.log # Nginx 错误日志 -
✅ 备份数据库(定期):
sudo -u postgres pg_dump mysite_db > ~/backup/mysite_$(date +%F).sql -
✅ 安全加固(进阶):
- 配置 UFW 防火墙:
sudo ufw allow OpenSSH && sudo ufw allow 'Nginx Full' && sudo ufw enable - 禁用密码登录(只用 SSH 密钥)
- 定期
apt update && apt upgrade
- 配置 UFW 防火墙:
🎯 总结:部署成功的关键四步
- 环境隔离:用
venv+ 专用用户deploy - 静态分离:
collectstatic+ Nginx 直接服务/static/ - 进程守护:
systemd管理 Gunicorn(非前台运行!) - HTTPS 强制:
certbot --nginx一键启用
需要我帮你:
- ✅ 自动生成
requirements.txt模板? - ✅ 提供一个最小可运行 Django 项目示例(含
.env+gunicorn.conf)? - ✅ 写一个一键部署脚本(bash)?
- ✅ 解释如何对接阿里云/腾讯云的 DNS + SSL?
欢迎随时告诉我 👇 我会为你定制补充!祝你部署顺利,网站早日上线 🚀
CLOUD云枢