在生产环境中,将 Django 静态文件托管到 CDN 的核心做法是修改 STATIC_URL 指向 CDN 域名,并确保静态文件已同步至 CDN 源站。为避免硬编码带来的环境切换风险,建议通过环境变量管理 CDN 地址,并根据 Django 版本正确配置存储后端。
核心步骤:
- 配置:使用环境变量动态设置
STATIC_URL和存储后端 - 收集:运行
collectstatic整理静态资源 - 同步:通过 CLI 或 CI/CD 将文件上传至对象存储
- 验证:检查浏览器 Network 面板确认资源命中 CDN
核心配置与环境变量管理
直接在 settings.py 中硬编码 CDN 域名会导致开发环境与生产环境配置冲突。建议结合 os.environ 或 python-decouple 读取环境变量,确保灵活性。
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# 优先读取环境变量,本地开发默认使用本地静态路径
STATIC_URL = os.environ.get('CDN_STATIC_URL', '/static/')
# 生产环境收集静态文件的目标目录
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# 本地开发时额外查找静态文件的目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]若使用 .env 文件管理配置,生产环境部署时需在服务器或容器环境中注入 CDN_STATIC_URL=https://cdn.example.com/static/。
存储后端与版本适配
Django 4.2 版本对存储配置进行了重构,旧版 STATICFILES_STORAGE 已被弃用。若需实现文件哈希缓存(文件内容变更则 URL 变更),需根据版本选择配置方式。
Django 4.2+ 配置方式:
STORAGES = {
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}Django 4.1 及以下版本:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'集成 django-storages(以 AWS S3 为例):
若使用对象存储作为 CDN 源站,需安装 django-storages 和 boto3,并在 settings.py 中配置后端:
INSTALLED_APPS += ['storages']
# 存储后端配置
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}
# AWS 凭证建议通过环境变量注入
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_CUSTOM_DOMAIN = os.environ.get('CDN_DOMAIN') # CDN 域名
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}文件收集与同步部署
静态文件需先收集到本地目录,再同步至远程存储。建议在 CI/CD 流水线或部署脚本中自动化此过程。
1. 收集静态文件:
python manage.py collectstatic `--noinput`2. 同步至对象存储:
若未使用 django-storages 自动上传,需手动同步 STATIC_ROOT 目录。
# AWS S3 示例
aws s3 sync ./staticfiles s3://your-bucket-name/static/ `--delete`
# 阿里云 OSS 示例 (ossutil)
ossutil sync ./staticfiles oss://your-bucket/static/ -r `--delete`3. CI/CD 自动化建议:
在 GitHub Actions 或 GitLab CI 中,可在部署阶段加入收集与同步步骤,确保每次代码更新后静态资源及时刷新。
验证与排查
部署完成后,需确认请求是否真正命中 CDN 节点。
1. 浏览器开发者工具:
打开页面按 F12 进入 Network 面板,刷新页面,查看 CSS/JS 文件的 Request URL 是否变为 CDN 域名。
2. 检查响应头:
在 Network 面板点击具体资源,查看 Response Headers,确认 Server 字段或 Via 字段显示 CDN 厂商标识(如 Cloudflare, Aliyun CDN 等)。
3. 命令行测试:
curl -I https://cdn.example.com/static/css/style.css观察返回头中是否包含 x-cache 或特定 CDN 标识字段。
常见风险
1. 缓存更新问题:
如果文件内容更新但文件名不变,CDN 可能仍缓存旧文件。启用 ManifestStaticFilesStorage 后,Django 会在文件名中加入内容哈希值(如 style.abc123.css),确保文件更新时 URL 变更,强制浏览器重新请求。
2. 混合内容错误(Mixed Content):
如果站点启用 HTTPS,确保 STATIC_URL 也使用 https 协议,否则浏览器会拦截不安全资源。建议配置 SECURE_SSL_REDIRECT = True 强制跳转。
3. 权限与跨域(CORS):
若静态文件涉及字体或跨域请求(如 Web Font),需在 CDN 或对象存储桶上配置 CORS 规则,允许相应域名访问,否则控制台会报 Access-Control-Allow-Origin 错误。
参考来源
- Django Documentation, Managing static files, https://docs.djangoproject.com/en/stable/howto/static-files/
- Django 4.2 Release Notes, https://docs.djangoproject.com/en/4.2/releases/4.2/