第17章:部署上线
17.2 部署方案
在上一节中,我们学习了如何配置Django生产环境。本节将介绍几种常见的Django部署方案,包括使用Nginx + Gunicorn的传统部署方式、云平台部署以及静态文件CDN加速。
Nginx + Gunicorn
Nginx + Gunicorn是Django应用最常见的部署组合。Nginx作为反向代理服务器处理静态文件和负载均衡,Gunicorn作为WSGI服务器运行Django应用。
Gunicorn配置
首先安装Gunicorn:
bash
pip install gunicorn创建Gunicorn配置文件:
python
# gunicorn.conf.py
import multiprocessing
# 服务器套接字
bind = "127.0.0.1:8000"
backlog = 2048
# 工作进程
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
# 重启策略
max_requests = 1000
max_requests_jitter = 100
# 日志
loglevel = "info"
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
# 进程命名
proc_name = "myproject"
# 服务器力学
preload_app = True
daemon = False
pidfile = "/var/run/gunicorn.pid"
user = "www-data"
group = "www-data"
# SSL(如果直接使用Gunicorn处理HTTPS)
# keyfile = "/path/to/keyfile"
# certfile = "/path/to/certfile"
# 性能调优
worker_tmp_dir = "/dev/shm"启动Gunicorn:
bash
# 使用配置文件启动
gunicorn --config gunicorn.conf.py myproject.wsgi:application
# 或者直接启动
gunicorn myproject.wsgi:application --bind 127.0.0.1:8000 --workers 3Nginx配置
安装Nginx:
bash
# Ubuntu/Debian
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install nginx创建Nginx站点配置:
nginx
# /etc/nginx/sites-available/myproject
upstream app_server {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80;
server_name yourdomain.com;
# 重定向到HTTPS(如果配置了SSL)
# return 301 https://$server_name$request_uri;
client_max_body_size 10M;
# 静态文件处理
location /static/ {
alias /var/www/myproject/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/myproject/media/;
expires 30d;
add_header Cache-Control "public";
}
# 动态请求转发给Gunicorn
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
}
# HTTPS配置(如果需要)
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# 启用HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# 其他配置与HTTP服务器相同
client_max_body_size 10M;
location /static/ {
alias /var/www/myproject/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/myproject/media/;
expires 30d;
add_header Cache-Control "public";
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}启用站点并重启Nginx:
bash
# 启用站点
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
# 测试配置
sudo nginx -t
# 重启Nginx
sudo systemctl restart nginx系统服务配置
为了确保Gunicorn在系统启动时自动运行,我们可以创建一个systemd服务:
ini
# /etc/systemd/system/myproject.service
[Unit]
Description=MyProject Django Application
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myproject
ExecStart=/var/www/myproject/venv/bin/gunicorn --config gunicorn.conf.py myproject.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
# 环境变量
Environment=DJANGO_ENV=production
Environment=DJANGO_SECRET_KEY=your-secret-key
Environment=DB_PASSWORD=your-db-password
[Install]
WantedBy=multi-user.target启动并启用服务:
bash
# 重新加载systemd配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start myproject
# 设置开机自启
sudo systemctl enable myproject
# 检查服务状态
sudo systemctl status myproject云平台部署
现代Django应用也可以部署到各种云平台,包括Heroku、AWS、Google Cloud、Azure等。
Heroku部署
- 创建Procfile:
web: gunicorn myproject.wsgi:application --log-file -- 创建runtime.txt指定Python版本:
python-3.11.5- 安装并配置django-heroku:
bash
pip install django-herokupython
# settings/production.py
import django_heroku
# 在文件末尾激活Heroku配置
django_heroku.settings(locals())- 部署到Heroku:
bash
# 安装Heroku CLI并登录
heroku login
# 创建应用
heroku create myproject
# 设置环境变量
heroku config:set DJANGO_ENV=production
heroku config:set DJANGO_SECRET_KEY=your-secret-key
# 部署代码
git push heroku mainDocker部署
创建Dockerfile:
dockerfile
# Dockerfile
FROM python:3.11-slim
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt /app/
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目文件
COPY . /app/
# 创建非root用户
RUN adduser --disabled-password --gecos '' appuser && \
chown -R appuser:appuser /app
USER appuser
# 暴露端口
EXPOSE 8000
# 运行应用
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]创建docker-compose.yml:
yaml
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DJANGO_ENV=production
- DJANGO_SECRET_KEY=your-secret-key
volumes:
- static_volume:/var/www/myproject/staticfiles
- media_volume:/var/www/myproject/media
depends_on:
- db
- redis
db:
image: postgres:15
environment:
- POSTGRES_DB=myproject
- POSTGRES_USER=myproject
- POSTGRES_PASSWORD=your-db-password
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- static_volume:/var/www/myproject/staticfiles
- media_volume:/var/www/myproject/media
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:静态文件CDN
为了提高静态文件的加载速度,可以将静态文件部署到CDN上。
使用AWS S3和CloudFront
- 安装依赖:
bash
pip install django-storages boto3- 配置settings:
python
# settings/production.py
import os
# AWS配置
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = os.environ.get('AWS_S3_REGION_NAME', 'us-east-1')
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
# 静态文件存储
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
# 媒体文件存储
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
# S3设置
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
AWS_S3_VERIFY = True- 收集静态文件:
bash
python manage.py collectstatic --noinput使用阿里云OSS
- 安装依赖:
bash
pip install django-oss-storage- 配置settings:
python
# settings/production.py
import os
# 阿里云OSS配置
OSS_ACCESS_KEY_ID = os.environ.get('OSS_ACCESS_KEY_ID')
OSS_ACCESS_KEY_SECRET = os.environ.get('OSS_ACCESS_KEY_SECRET')
OSS_BUCKET_NAME = os.environ.get('OSS_BUCKET_NAME')
OSS_ENDPOINT = os.environ.get('OSS_ENDPOINT')
# 静态文件存储
STATICFILES_STORAGE = 'django_oss_storage.backends.OssStaticStorage'
STATIC_URL = f'https://{OSS_BUCKET_NAME}.{OSS_ENDPOINT}/static/'
# 媒体文件存储
DEFAULT_FILE_STORAGE = 'django_oss_storage.backends.OssMediaStorage'
MEDIA_URL = f'https://{OSS_BUCKET_NAME}.{OSS_ENDPOINT}/media/'使用腾讯云COS
- 安装依赖:
bash
pip install qcloud_cos django-cos-storage- 配置settings:
python
# settings/production.py
import os
# 腾讯云COS配置
COS_SECRET_ID = os.environ.get('COS_SECRET_ID')
COS_SECRET_KEY = os.environ.get('COS_SECRET_KEY')
COS_REGION = os.environ.get('COS_REGION')
COS_BUCKET = os.environ.get('COS_BUCKET')
# 静态文件存储
STATICFILES_STORAGE = 'django_cos_storage.backends.CosStaticStorage'
STATIC_URL = f'https://{COS_BUCKET}.cos.{COS_REGION}.myqcloud.com/static/'
# 媒体文件存储
DEFAULT_FILE_STORAGE = 'django_cos_storage.backends.CosMediaStorage'
MEDIA_URL = f'https://{COS_BUCKET}.cos.{COS_REGION}.myqcloud.com/media/'监控和维护
部署完成后,还需要考虑应用的监控和维护。
健康检查端点
创建健康检查视图:
python
# views.py
from django.http import JsonResponse
from django.db import connections
from django.db.utils import OperationalError
import redis
import os
def health_check(request):
"""健康检查端点"""
health_status = {
'status': 'healthy',
'database': check_database(),
'redis': check_redis(),
'disk_space': check_disk_space(),
}
# 如果有任何组件不健康,返回错误状态
if not all(health_status.values()):
health_status['status'] = 'unhealthy'
return JsonResponse(health_status, status=503)
return JsonResponse(health_status)
def check_database():
"""检查数据库连接"""
db_conn = connections['default']
try:
c = db_conn.cursor()
return True
except OperationalError:
return False
def check_redis():
"""检查Redis连接"""
try:
redis_client = redis.Redis(
host=os.environ.get('REDIS_HOST', 'localhost'),
port=os.environ.get('REDIS_PORT', 6379),
db=0
)
redis_client.ping()
return True
except:
return False
def check_disk_space():
"""检查磁盘空间"""
try:
stat = os.statvfs('/')
free_bytes = stat.f_bavail * stat.f_frsize
# 如果剩余空间小于1GB,认为不健康
return free_bytes > 1024 * 1024 * 1024
except:
return False配置URL:
python
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('health/', views.health_check, name='health_check'),
# 其他URL...
]自动化部署脚本
创建部署脚本:
bash
#!/bin/bash
# deploy.sh
set -e # 遇到错误时退出
echo "开始部署..."
# 拉取最新代码
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 myproject
sudo systemctl restart nginx
echo "部署完成!"备份策略
创建数据库备份脚本:
bash
#!/bin/bash
# backup.sh
# 数据库备份
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_DIR="/var/backups/myproject"
mkdir -p $BACKUP_DIR
# PostgreSQL备份
pg_dump myproject > $BACKUP_DIR/db_backup_$DATE.sql
# 压缩备份
gzip $BACKUP_DIR/db_backup_$DATE.sql
# 删除7天前的备份
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete
# 媒体文件备份(如果存储在本地)
tar -czf $BACKUP_DIR/media_backup_$DATE.tar.gz /var/www/myproject/media/
# 删除7天前的媒体文件备份
find $BACKUP_DIR -name "media_backup_*.tar.gz" -mtime +7 -delete小结
Django部署方案的核心要点:
- ✅ Nginx + Gunicorn是传统部署的经典组合
- ✅ 云平台部署提供了更便捷的部署方式
- ✅ 使用CDN加速静态文件访问
- ✅ 实施监控和健康检查确保应用稳定
- ✅ 建立自动化部署和备份策略
选择合适的部署方案取决于项目需求、团队技能和预算考虑。无论选择哪种方案,都需要确保应用的安全性、稳定性和可扩展性。
通过本章的学习,您已经掌握了Django生产环境配置和部署的完整流程。在实际项目中,建议根据具体情况调整配置,并持续优化部署流程。
🎉Django 深入浅出系列课程
恭喜您完成了整个Django 深入浅出系列课程!通过本课程的学习,您已经掌握了:
核心技能掌握
- ✅ Django MTV架构和项目结构
- ✅ 模型设计和数据库操作
- ✅ 视图开发和URL路由
- ✅ 模板系统和表单处理
- ✅ 用户认证和权限管理
高级特性应用
- ✅ Admin后台定制
- ✅ RESTful API开发
- ✅ 测试驱动开发
- ✅ 性能优化技巧
- ✅ 生产环境部署
实战项目经验
- ✅ 完整的博客系统开发
- ✅ 前后端分离架构
- ✅ 持续集成和自动化部署
- ✅ 监控和维护策略
下一步建议
- 实践项目:尝试开发一个完整的个人项目
- 深入学习:探索Django Channels、Celery等高级特性
- 社区参与:加入Django社区,参与开源项目
- 持续学习:关注Django最新版本和最佳实践
感谢您学习本课程!祝您在Django开发之路上越走越远!