努力
奋斗

新手如何在云服务器上从零部署Python Django网站应用?

服务器

从零部署 Django 网站应用到云服务器

📋 整体架构概览

用户浏览器 → Nginx(反向X_X/静态文件) → Gunicorn(WSGI服务器) → Django应用
                          ↑                    ↑
                      SSL证书              Python虚拟环境

第一步:准备云服务器

1.1 选择系统(推荐 Ubuntu 22.04 LTS)

# SSH 登录服务器
ssh root@your_server_ip

# 更新系统
apt update && apt upgrade -y

1.2 创建非 root 用户并配置 sudo

# 创建新用户
adduser deployer

# 赋予 sudo 权限
usermod -aG sudo deployer

# 切换到新用户
su - deployer

第二步:安装基础软件

2.1 安装 Python 和 pip

# 安装 Python 3 及必要依赖
sudo apt install python3-pip python3-venv python3-dev libpq-dev 
    build-essential libssl-dev libffi-dev -y

# 验证版本
python3 --version
pip3 --version

2.2 安装 PostgreSQL(推荐数据库)

# 安装 PostgreSQL
sudo apt install postgresql postgresql-contrib -y

# 启动服务
sudo systemctl start postgresql
sudo systemctl enable postgresql

# 创建数据库和用户
sudo -u postgres psql
-- 在 psql 中执行:
CREATE DATABASE myproject_db;
CREATE USER myproject_user WITH PASSWORD 'your_strong_password';
ALTER ROLE myproject_user SET client_encoding TO 'utf8';
ALTER ROLE myproject_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE myproject_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE myproject_db TO myproject_user;
q

备选:如果只用 SQLite,可跳过此步,但生产环境强烈建议用 PostgreSQL。

2.3 安装 Nginx

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

2.4 安装 Gunicorn

pip3 install gunicorn

第三步:部署 Django 项目

3.1 上传代码到服务器

# 方式一:Git 拉取(推荐)
git clone https://github.com/yourusername/your-django-project.git ~/myproject

# 方式二:SCP 上传本地项目
scp -r ./myproject/* deployer@your_server_ip:~/myproject/

3.2 创建虚拟环境并安装依赖

cd ~/myproject

# 创建虚拟环境
python3 -m venv venv

# 激活虚拟环境
source venv/bin/activate

# 升级 pip
pip install --upgrade pip

# 安装依赖
pip install -r requirements.txt

# 常见依赖示例 (requirements.txt):
# Django==4.2.7
# psycopg2-binary==2.9.9
# gunicorn==21.2.0
# django-environ==0.11.2
# whitenoise==6.6.0

3.3 配置 Django settings.py

关键修改点:

# myproject/settings.py

import environ
import os

env = environ.Env(
    DEBUG=(bool, False)
)
environ.Env.read_env()  # 从 .env 文件读取环境变量

BASE_DIR = Path(__file__).resolve().parent.parent

# 🔒 安全设置
SECRET_KEY = env('SECRET_KEY')  # 从环境变量读取,不要硬编码!
DEBUG = env('DEBUG', default=False)

ALLOWED_HOSTS = ['your_domain.com', 'www.your_domain.com', 'your_server_ip']

# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': env('DB_NAME'),       # myproject_db
        'USER': env('DB_USER'),        # myproject_user
        'PASSWORD': env('DB_PASSWORD'),# your_strong_password
        'HOST': env('DB_HOST', default='localhost'),
        'PORT': env('DB_PORT', default='5432'),
    }
}

# 静态文件配置
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

# 媒体文件配置
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# 白名单域名(防止 Host Header 攻击)
if not DEBUG:
    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
    SECURE_HSTS_SECONDS = 31536000
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
    SECURE_HSTS_PRELOAD = True

3.4 创建 .env 文件(放在项目根目录,加入 .gitignore)

# .env
DEBUG=False
SECRET_KEY=your_super_secret_key_here_change_this
DB_NAME=myproject_db
DB_USER=myproject_user
DB_PASSWORD=your_strong_password
DB_HOST=localhost
DB_PORT=5432
ALLOWED_HOSTS=your_domain.com,www.your_domain.com,your_server_ip
# 确保 .env 不被提交到 Git
echo ".env" >> .gitignore

3.5 收集静态文件并迁移数据库

# 激活虚拟环境
source venv/bin/activate

# 收集静态文件
python manage.py collectstatic --noinput

# 执行数据库迁移
python manage.py migrate

# 创建超级管理员(可选)
python manage.py createsuperuser

# 测试运行
python manage.py runserver 0.0.0.0:8000

访问 http://your_server_ip:8000 确认 Django 正常运行。


第四步:配置 Gunicorn

4.1 创建 systemd 服务文件

sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon for myproject
Requires=gunicorn.socket
After=network.target

[Service]
User=deployer
Group=www-data
WorkingDirectory=/home/deployer/myproject
Environment="PATH=/home/deployer/myproject/venv/bin"
ExecStart=/home/deployer/myproject/venv/bin/gunicorn 
          --access-logfile - 
          --workers 3 
          --bind unix:/home/deployer/myproject/myproject.sock 
          myproject.wsgi:application

[Install]
WantedBy=multi-user.target

注意:将 myproject.wsgi:application 中的 myproject 替换为你的实际 WSGI 模块名(即包含 wsgi.py 的目录名)。

4.2 设置权限并启动

# 给 sock 文件所在目录正确的权限
sudo chown -R deployer:www-data /home/deployer/myproject

# 重新加载 systemd
sudo systemctl daemon-reload

# 启动 Gunicorn
sudo systemctl start gunicorn
sudo systemctl enable gunicorn

# 检查状态
sudo systemctl status gunicorn

第五步:配置 Nginx

5.1 创建 Nginx 站点配置

sudo nano /etc/nginx/sites-available/myproject
server {
    listen 80;
    server_name your_domain.com www.your_domain.com;

    # 重定向 HTTP 到 HTTPS(后续配置 SSL 后启用)
    # return 301 https://$host$request_uri;

    location /static/ {
        alias /home/deployer/myproject/staticfiles/;
        # 缓存静态文件
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location /media/ {
        alias /home/deployer/myproject/media/;
        expires 30d;
        add_header Cache-Control "public";
    }

    location / {
        proxy_pass http://unix:/home/deployer/myproject/myproject.sock;
        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;

        # WebSocket 支持(如有需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

5.2 启用站点并测试配置

# 创建软链接
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/

# 删除默认站点(避免冲突)
sudo rm /etc/nginx/sites-enabled/default

# 测试 Nginx 配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx
sudo systemctl enable nginx

第六步:配置 SSL 证书(HTTPS)

6.1 使用 Let’s Encrypt(免费)

# 安装 Certbot
sudo apt install certbot python3-certbot-nginx -y

# 获取证书(Nginx 插件会自动配置)
sudo certbot --nginx -d your_domain.com -d www.your_domain.com

Certbot 会:

  • 自动下载 SSL 证书
  • 修改 Nginx 配置添加 HTTPS
  • 设置自动续期

6.2 手动配置 SSL(如果使用其他证书)

server {
    listen 443 ssl http2;
    server_name your_domain.com www.your_domain.com;

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;

    # 推荐的安全参数
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location /static/ {
        alias /home/deployer/myproject/staticfiles/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location /media/ {
        alias /home/deployer/myproject/media/;
        expires 30d;
        add_header Cache-Control "public";
    }

    location / {
        proxy_pass http://unix:/home/deployer/myproject/myproject.sock;
        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;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name your_domain.com www.your_domain.com;
    return 301 https://$host$request_uri;
}
sudo nginx -t && sudo systemctl reload nginx

6.3 设置自动续期

# 测试续期
sudo certbot renew --dry-run

# 创建定时任务自动续期
sudo crontab -e
# 每天凌晨2点检查并续期证书
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

第七步:防火墙与安全加固

7.1 配置 UFW 防火墙

sudo apt install ufw -y

# 允许 SSH、HTTP、HTTPS
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'  # 同时开放 80 和 443

# 启用防火墙
sudo ufw enable

# 查看状态
sudo ufw status

7.2 禁用 root SSH 登录

sudo nano /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
# 先配置好 SSH 密钥认证再重启
sudo systemctl restart sshd

7.3 配置 fail2ban(防暴力破解)

sudo apt install fail2ban -y

# 创建自定义配置
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

第八步:日志与监控

8.1 查看 Gunicorn 日志

# Gunicorn 日志输出到 stdout,由 systemd 管理
journalctl -u gunicorn -f

# 查看最近错误
journalctl -u gunicorn -p err -n 50

8.2 查看 Nginx 日志

tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

8.3 配置 Django 日志

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'file': {
            'level': 'ERROR',
            'class': 'logging.FileHandler',
            'filename': '/home/deployer/myproject/logs/django.log',
            'formatter': 'verbose',
        },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'console'],
            'level': 'WARNING',
            'propagate': True,
        },
        'myproject': {
            'handlers': ['file', 'console'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}
mkdir -p /home/deployer/myproject/logs
touch /home/deployer/myproject/logs/django.log
chown deployer:deployer /home/deployer/myproject/logs/django.log

🗂️ 完整目录结构

/home/deployer/myproject/
├── manage.py
├── myproject/              # Django 项目配置目录
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py             # ← Gunicorn 指向这个文件
│   └── asgi.py
├── app/                    # 你的 Django App
│   ├── models.py
│   ├── views.py
│   └── ...
├── staticfiles/            # collectstatic 生成
├── media/                  # 用户上传的文件
├── logs/
│   └── django.log
├── venv/                   # Python 虚拟环境
├── myproject.sock          # Gunicorn Unix socket
├── requirements.txt
├── .env                    # 敏感配置(不在 Git 中)
└── .gitignore

✅ 部署检查清单

检查项 命令/操作
系统更新 apt update && apt upgrade -y
Python 版本 python3 --version
PostgreSQL 运行 sudo systemctl status postgresql
虚拟环境激活 source venv/bin/activate
依赖安装 pip install -r requirements.txt
数据库迁移 python manage.py migrate
静态文件收集 python manage.py collectstatic --noinput
Gunicorn 运行 sudo systemctl status gunicorn
Nginx 运行 sudo systemctl status nginx
SSL 证书有效 curl -I https://your_domain.com
防火墙规则 sudo ufw status
网站可访问 浏览器访问 https://your_domain.com

🔄 CI/CD 自动化部署(进阶)

使用 GitHub Actions 自动部署

# .github/workflows/deploy.yml
name: Deploy to Server

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Deploy via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_IP }}
          username: deployer
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd ~/myproject
            git pull origin main
            source venv/bin/activate
            pip install -r requirements.txt
            python manage.py migrate --noinput
            python manage.py collectstatic --noinput
            sudo systemctl restart gunicorn

⚠️ 常见陷阱与解决

问题 原因 解决方案
403 Forbidden 权限不足 sudo chown -R deployer:www-data /path/to/project
502 Bad Gateway Gunicorn 未运行或 socket 路径错误 sudo systemctl status gunicorn
静态文件 404 Nginx 静态路径配置错误 检查 alias 路径是否正确
数据库连接失败 用户/密码/数据库名不匹配 检查 .env 和 PostgreSQL 用户权限
CORS 错误 前后端分离时跨域 安装 django-cors-headers 并配置
内存不足 Workers 过多 减少 Gunicorn workers 数量 (--workers 2)

📊 性能优化建议

# settings.py 额外优化
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # 替代 Nginx 处理部分静态文件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# 启用数据库查询缓存
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }
}
# 安装 Redis 作为缓存后端
sudo apt install redis-server -y
sudo systemctl enable redis-server
pip install django-redis

按照以上步骤,你就可以成功将 Django 项目部署到云服务器上。核心流程就是:Python 环境 → Django 运行 → Gunicorn 服务化 → Nginx 反向X_X → SSL 加密。每一步都经过验证,适合新手循序渐进完成。

未经允许不得转载:轻量云Cloud » 新手如何在云服务器上从零部署Python Django网站应用?