Python Django生产环境部署:Gunicorn + Nginx + PostgreSQL香港VPS完整配置
Django是Python最成熟的全栈Web框架,广泛用于SaaS平台、内容管理系统和API后端。本文给出香港VPS上Django生产环境的完整部署方案,包括进程管理、数据库优化和异步任务处理。
一、环境准备
<code"># 安装Python 3.11+和系统依赖
apt update
apt install python3.11 python3.11-venv python3.11-dev \
postgresql postgresql-contrib libpq-dev \
nginx redis-server -y
# 创建项目专用用户(安全隔离)
useradd -m -s /bin/bash django
su - django
# 创建虚拟环境
python3.11 -m venv /srv/myapp/venv
source /srv/myapp/venv/bin/activate
# 安装Django和生产依赖
pip install django gunicorn psycopg2-binary \
django-redis celery redis whitenoise \
django-storages boto3 sentry-sdk二、Django生产环境配置
<code"># myapp/settings/production.py
import os
import sentry_sdk
from .base import *
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
# ============ 数据库(PostgreSQL)============
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
'CONN_MAX_AGE': 60, # 连接池复用60秒
'OPTIONS': {
'sslmode': 'prefer',
},
}
}
# ============ 缓存(Redis)============
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': f"redis://:{os.environ['REDIS_PASSWORD']}@127.0.0.1:6379/1",
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'SOCKET_CONNECT_TIMEOUT': 5,
'SOCKET_TIMEOUT': 5,
},
'TIMEOUT': 300,
}
}
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
# ============ 静态文件 ============
STATIC_URL = '/static/'
STATIC_ROOT = '/srv/myapp/staticfiles'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# ============ 媒体文件(Cloudflare R2)============
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID = os.environ['R2_ACCESS_KEY']
AWS_SECRET_ACCESS_KEY = os.environ['R2_SECRET_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['R2_BUCKET']
AWS_S3_ENDPOINT_URL = os.environ['R2_ENDPOINT']
MEDIA_URL = f"https://media.yourdomain.com/"
# ============ 安全配置 ============
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
# ============ 日志 ============
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/django/error.log',
'maxBytes': 50 * 1024 * 1024,
'backupCount': 5,
'formatter': 'verbose',
},
'console': {
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'root': {
'handlers': ['file', 'console'],
'level': 'WARNING',
},
}
# ============ Celery(异步任务)============
CELERY_BROKER_URL = f"redis://:{os.environ['REDIS_PASSWORD']}@127.0.0.1:6379/0"
CELERY_RESULT_BACKEND = CELERY_BROKER_URL
CELERY_TASK_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TIMEZONE = 'Asia/Shanghai'
# ============ Sentry错误监控 ============
sentry_sdk.init(
dsn=os.environ.get('SENTRY_DSN', ''),
traces_sample_rate=0.1,
profiles_sample_rate=0.1,
)三、Gunicorn配置
<code"># /srv/myapp/gunicorn.conf.py import multiprocessing # Worker数量:CPU核心数 × 2 + 1 workers = multiprocessing.cpu_count() * 2 + 1 # Worker类型:gevent适合I/O密集型应用 worker_class = 'sync' # 同步(无额外依赖) # worker_class = 'gevent' # 异步(需要pip install gevent) # 请求超时 timeout = 120 graceful_timeout = 30 # 绑定地址(Unix Socket性能优于TCP) bind = 'unix:/run/gunicorn/myapp.sock' # 日志 accesslog = '/var/log/gunicorn/access.log' errorlog = '/var/log/gunicorn/error.log' loglevel = 'warning' access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(L)ss' # 安全 limit_request_line = 4096 limit_request_fields = 100 # 性能 keepalive = 5 max_requests = 1000 max_requests_jitter = 100
<code"># /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn Django Application Server
After=network.target postgresql.service redis.service
[Service]
Type=notify
User=django
Group=www-data
RuntimeDirectory=gunicorn
WorkingDirectory=/srv/myapp
EnvironmentFile=/srv/myapp/.env.production
ExecStart=/srv/myapp/venv/bin/gunicorn \
--config /srv/myapp/gunicorn.conf.py \
myapp.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target<code"># 创建运行目录并设置权限 mkdir -p /run/gunicorn /var/log/gunicorn /var/log/django chown django:www-data /run/gunicorn /var/log/gunicorn /var/log/django systemctl daemon-reload systemctl enable gunicorn systemctl start gunicorn
四、Nginx配置
<code">server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
client_max_body_size 20M;
# 静态文件由Nginx直接提供(不经过Gunicorn)
location /static/ {
alias /srv/myapp/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 动态请求转发到Gunicorn
location / {
proxy_pass http://unix:/run/gunicorn/myapp.sock;
proxy_http_version 1.1;
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;
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
# Django CSRF
proxy_set_header X-CSRFToken $http_x_csrftoken;
}
}五、PostgreSQL优化
<code"># 查看推荐配置(根据服务器内存自动计算) # 访问 https://pgtune.leopard.in.ua 填入服务器规格获取推荐值 # /etc/postgresql/15/main/postgresql.conf 关键参数 # 内存(4G服务器参考值) shared_buffers = 1GB # 25%物理内存 effective_cache_size = 3GB # 75%物理内存 work_mem = 16MB # 每个查询的内存 maintenance_work_mem = 256MB # 维护操作内存 # 连接 max_connections = 100 # 写入性能 wal_buffers = 16MB checkpoint_completion_target = 0.9 default_statistics_target = 100 # 慢查询日志 log_min_duration_statement = 1000 # 记录超过1秒的查询 log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
六、Celery异步任务
<code"># myapp/tasks.py
from celery import shared_task
from django.core.mail import send_mail
import time
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def send_order_email(self, order_id: int) -> dict:
"""发送订单确认邮件(异步任务)"""
try:
from orders.models import Order
order = Order.objects.select_related('user').get(pk=order_id)
send_mail(
subject=f'订单确认 #{order.order_number}',
message=f'您的订单已确认,总金额 ¥{order.total}',
from_email='noreply@yourdomain.com',
recipient_list=[order.user.email],
)
return {'status': 'sent', 'order_id': order_id}
except Exception as exc:
raise self.retry(exc=exc)
# 视图中调用(非阻塞,立即返回)
# send_order_email.delay(order_id=123)<code"># /etc/supervisor/conf.d/celery.conf [program:celery-worker] command=/srv/myapp/venv/bin/celery -A myapp worker -l WARNING -c 4 directory=/srv/myapp user=django environment=DJANGO_SETTINGS_MODULE="myapp.settings.production" autostart=true autorestart=true stderr_logfile=/var/log/celery/worker.err.log stdout_logfile=/var/log/celery/worker.out.log [program:celery-beat] command=/srv/myapp/venv/bin/celery -A myapp beat -l WARNING --scheduler django_celery_beat.schedulers:DatabaseScheduler directory=/srv/myapp user=django autostart=true autorestart=true stderr_logfile=/var/log/celery/beat.err.log
七、部署流程脚本
<code">#!/bin/bash # /usr/local/bin/django-deploy.sh set -e APP_DIR="/srv/myapp" VENV="$APP_DIR/venv" echo "🚀 开始部署Django应用..." cd "$APP_DIR" # 拉取最新代码 git pull origin main # 激活虚拟环境,安装/更新依赖 source "$VENV/bin/activate" pip install -r requirements/production.txt --quiet # 数据库迁移 python manage.py migrate --settings=myapp.settings.production --no-input # 收集静态文件 python manage.py collectstatic --settings=myapp.settings.production --no-input --clear # 零停机重载Gunicorn(发送HUP信号) systemctl reload gunicorn # 重启Celery Worker(让其加载新代码) supervisorctl restart celery-worker echo "✅ 部署完成 $(date)"
八、总结
Django生产部署的标准栈:Gunicorn(WSGI进程管理)+ Nginx(静态文件+反向代理)+ PostgreSQL(主数据库)+ Redis(缓存+Session+Celery Broker)。这套组合在香港VPS上经过大量生产验证,4核8G配置可支撑每秒数百个Django请求。IDC.Net的香港VPS预装Ubuntu 22.04,Python 3.11和PostgreSQL均可快速安装,是部署Django应用的理想平台。
版权声明:
作者:后浪云
链接:https://idc.net/help/442854/
文章版权归作者所有,未经允许请勿转载。
THE END
