django系列(N)之django项目部署

一、概述
django部署有多种可用的web服务器,如下所述:

同步项目:
gunicorn+nginx, gunicorn 纯python编写,配置简单,易上手,适合中小型项目,不支持高并发,与docker,k8s等非常适配
uwsgi+nginx, uwsgi 是c语言编写,配置较复杂,适合中大型高并发项目

异步项目:
daphne+nginx, daphne 支持异步,是asgi协议

本文介绍uwsgi+nginx的方式

二、部署
2.1、环境准备
# 1、准备一台linux服务器,本文部署使用的是redhat7.9

# 2、在linux中部署python ,本文使用的是python3.9.13,
python安装请见我另一篇博客:https://www.cnblogs.com/sunjiwei/articles/18066608

# 3、创建项目用户并配置sudo
useradd www

visudo  # 打开配置sudo的配置文件,然后在配置文件最后加入下面这行
www    ALL=(ALL)       NOPASSWD: ALL

# 4、在linux中部署nginx,yum install -y nginx
    或者也可以下载二进制包安装:
    1、下载地址:https://nginx.org/download/

    2、上传到服务器并解压
    tar -xvf nginx-1.24.0.tar.gz

    3、安装依赖
    yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel

    4、编译安装
    cd nginx-1.24.0/
    ./configure --prefix=/usr/local/nginx --with-http_ssl_module
    make && make install

    # 授权
    chown -R www:www /usr/local/nginx


# 5、创建项目目录并授权
mkdir -p /data/www
chown -R www:www /data/www
chmod -R 755 /data/www

# 6、进入项目目录
cd /data/www/wms_project

# 7、clone代码或上传代码
# 如果是clone,需要自行学习git的安装使用
git clone 你的代码仓库地址

# 重新授权
chown -R www:www /data/www
chmod -R 755 /data/www


# 8、创建虚拟环境(在/data/www/wms_project这个目录下创建虚拟环境)
python3 -m venv wms_venv # wms_venv  是虚拟环境名称

source /data/www/wms_project/wms_venv/bin/activate     # 激活虚拟环境

# 9、安装依赖
/data/www/wms_project/wms_venv/bin/python3 -m pip install --upgrade pip
pip3 install -r /data/www/wms_project/warehouse_management/requirements.txt -i https://mirrors.aliyun.com/pypi/simple

# 10、安装 uWSGI
pip3 install uwsgi  -i https://mirrors.aliyun.com/pypi/simple

2.2、配置django
1. 修改配置文件以适配生产环境(注意,我这里偷懒了,正常应该创建新的生产配置文件)
# 以下是需要修改的项或者需要添加的项,其他配置项正常用就可以

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

# 一定要改为False
DEBUG = False        

# 允许访问的域名(填服务器IP/域名,多个用逗号分隔)
ALLOWED_HOSTS = ['*']           #  ['your-domain.com',  '服务器IP']. 正常这样配,我这里直接*了

# 以下三个静态文件配置
STATIC_URL = '/static/'      # 静态文件访问url配置
# 静态文件存储路径,只需要配置全局的static文件夹即可,不需要配置每个app下的static文件夹,django会自动去app下寻找
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
STATIC_ROOT = os.path.join(PARENT_BASE_DIR, 'staticfiles')  # 这个是收集静态文件后存放文件的目录

# 媒体文件配置
MEDIA_URL = '/media/'     
MEDIA_ROOT = os.path.join(PARENT_BASE_DIR, 'media')    

# 密钥(生产环境务必替换为随机字符串,建议从环境变量读取)
# export DJANGO_SECRET_KEY='一长串随机字符'.  这个在linux服务器上配置环境变量
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') # 然后读取环境变量

# 用 Django 自带命令生成一个安全的 SECRET_KEY
# python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'

# 数据库配置,修改为生产环境的配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'your_db_name',
        'USER': 'your_db_user',
        'PASSWORD': 'your_db_pwd',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4'
        }
    }
}

# 日志配置
# 日志配置
# ===================== 日志目录创建 =====================
LOG_DIR = os.path.join(PARENT_BASE_DIR, 'log')
os.makedirs(LOG_DIR, exist_ok=True)  # 自动创建日志目录(不存在时)

# ===================== 核心日志配置 =====================
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,  # 不禁用其他已存在的 logger
    'formatters': {  
        'verbose': {
            'format': '{asctime} 【{levelname}】{module} 进程ID-{process:d} 线程ID-{thread:d} {message} {exc_info}',
            'style': '{',
            "datefmt": "%Y-%m-%d %H:%M:%S",
        },

        # 业务日志格式:侧重业务语义,无技术细节
        "business": {
            "format": "[{asctime}] {levelname} {name} {module}.{funcName}:{lineno} - {message}",
            "style": "{",
            "datefmt": "%Y-%m-%d %H:%M:%S",
        },
    },
    'handlers': {
        'prod_file': {  
            'level': 'WARNING',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'when': 'D',  # 按天轮转(可选S/秒、M/分、H/时、D/天、W0-6/周)
            'backupCount': 30,
            'filename': os.path.join(LOG_DIR, 'django_error.log'),  # 错误日志文件路径
            'formatter': 'verbose',
            'encoding': 'utf-8',
        },

        "business_file": {  # 业务日志处理器
            "level": "INFO",
            "class": "logging.handlers.TimedRotatingFileHandler",  # 按时间轮转
            "filename": os.path.join(LOG_DIR , "business.log"),  # 业务日志文件路径
            "when": "D",  # 每天轮转
            "backupCount": 30,  # 保留30天
            "encoding": "utf-8",
            "formatter": "business",
        },

        "mail": {  # 严重错误邮件告警(生产),可选
            "level": "ERROR",
            "class": "django.utils.log.AdminEmailHandler",
            "formatter": "verbose",
            "include_html": False,  # 不发送HTML格式,避免泄露细节
        },
    },

    'root': {
        'handlers': ['prod_file'],
    },

    'loggers': {
        # ---------------- Django核心日志器 ----------------
        "django.request": {  # HTTP请求日志(4xx/5xx)
            "handlers": ["prod_file"],
            "level": "WARNING",
            "propagate": False,
        },
        "django.db.backends": {  # 数据库日志
            "handlers": ["prod_file"],
            "level": "WARNING",
            "propagate": False,
        },
        "django.security": {
            "handlers": ["prod_file"],
            "level": "WARNING",
            "propagate": False,
        },
        'django': {  # django框架核心日志器
            'handlers': ['prod_file'],
            'level': 'WARNING',
            'propagate': False,
        },
        # ---------------- 业务日志器,可以为每个app都配置一个单独的,实现精细化的日志管理,也可以共用这一个 ----------------
        'common_app': {
            'handlers': ['business_file'],
            'level': 'INFO',
            'propagate': False,
        },
    },
}


2、收集静态文件
# 切换到www用户
su - www

# 激活虚拟环境(如果没激活)
source /data/www/your_project/env/bin/activate

# 进入项目源码目录
cd /data/www/wms_project/warehouse_management

# 收集静态文件到STATIC_ROOT目录下
python3 manage.py collectstatic --noinput  # --noinput 跳过确认

3、创建超级管理员(可选),供后续使用
python3 manage.py createsuperuser
2.3、uWSGI配置

su - www # 切到www用户下执行

1. 创建 uWSGI 配置文件
# 注意!!!:写配置文件时,要把这些注释都去掉,uWSGI配置文件不支持这些注释,会把他们当作配置

cat > /data/www/wms_project/conf/uwsgi.ini <<EOF
[uwsgi]
# 核心配置
chdir = /data/www/wms_project/warehouse_management         # 项目源码根目录(manage.py所在目录)
module =warehouse_management.wsgi:application              # Django 项目里的 WSGI 应用程序
home = /data/www/wms_project/wms_venv                      # 虚拟环境路径
listen = 100                        # 监听请求队列大小,即最多允许100个请求排队等待,django会把同一时刻超出workers * threads 的请求放到队列里,根据自己的并发调整
socket-timeout = 30                 # 请求队列中排队超时30秒,避免用户无限等待

# 进程/线程配置(根据服务器CPU核数调整)
master = true                             # 主进程
workers = 4                               # 工作进程数(建议:CPU核数*2+1),这是利用多核cpu的关键
threads = 2                               # 每个进程的线程数,建议最大不要超过4,单个cpu在多个线程之间切换调用
max-requests = 10000                      # 每个进程最大处理请求数(防止内存泄漏),每个 worker 进程处理完 10000 个请求后,uWSGI 会自动杀死这个 worker,并由主进程重启一个全新的 worker
# harakiri = 60                           # 请求开始后执行过程超时时间(秒)

# 如果没用 nginx,只想自己启动一个 http 界面,用这个调测
# http = 0.0.0.0:8000 # 直接作为 web 服务器,uwsgi也可以直接做服务器,只是对静态文件来说太慢,所以要配合nginx

# 网络配置(与Nginx通信)
socket = /data/www/wms_project/conf/uwsgi.sock  # UNIX Socket(比TCP更高效),只适用于nginx和uWSGI在同一个服务器机器的情况,如果nginx是单独的机器,需要用TCP, socket = 0.0.0.0:8000
uid = www                                       # 运行用户
gid = www                                       # 运行用户组

# 日志配置
daemonize = /data/www/wms_project/log/uwsgi.log  # 后台运行并输出日志
log-maxsize = 10485760  # 日志文件达到这个大小会生成下一个新的文件(对daemonize的日志文件同样起作用)
# 注释/删除 logto = xxx.log(避免冲突)
pidfile = /data/www/wms_project/conf/uwsgi.pid    # PID文件(用于重启/停止)

# 清理
vacuum = true                     # 退出时自动清理Socket文件
disable-logging = true            # 关闭默认请求日志(避免冗余)

# 环境变量,告诉 Django运行时使用哪个配置文件,是多环境(开发 / 测试 / 生产)隔离的核心配置,我这里前面搞django配置文件时偷懒了,原地修改配置文件的,所以注释掉不用
# 注意env 是 uWSGI 配置文件里的固定指令,不是python的虚拟环境,就这样写,只修改最后的配置文件的路径即可
# env = DJANGO_SETTINGS_MODULE=warehouse_management.settings.production
EOF


2、启动 / 停止 uWSGI 命令

# 如果用这些命令要切换到www用户下
su - www

# 激活虚拟环境(若未激活)
source /data/www/wms_project/wms_venv/bin/activate

# 启动uWSGI
/data/www/wms_project/wms_venv/bin/uwsgi --ini /data/www/wms_project/conf/uwsgi.ini

# 停止uWSGI
/data/www/wms_project/wms_venv/bin/uwsgi --stop /data/www/wms_project/conf/uwsgi.pid

# 重启uWSGI
/data/www/wms_project/wms_venv/bin/uwsgi --reload /data/www/wms_project/conf/uwsgi.pid


3、配置 systemd 服务(管理 uWSGI)
# 要在root用户下配置systemd
# 注意这里有个坑,如果要配置systemd,则uwsgi配置文件中的daemonize参数要给去掉,systemd不支持后台守护进程
# 日志使用logto 参数配置

cat > /etc/systemd/system/uwsgi_wms_project.service <<EOF
[Unit]
Description=uWSGI Service for Django Project
After=network.target   

[Service]
User=www
Group=www
# 指定「服务启动后切换到的工作目录」,可以把它理解为:系统启动这个服务时,先 “cd 到该目录”,再执行后续的启动命令(比如启动 uWSGI)。
WorkingDirectory=/data/www/wms_project
ExecStart=/data/www/wms_project/wms_venv/bin/uwsgi --ini /data/www/wms_project/conf/uwsgi.ini
ExecReload=/data/www/wms_project/wms_venv/bin/uwsgi --reload /data/www/wms_project/conf/uwsgi.ini
ExecStop=/data/www/wms_project/wms_venv/bin/uwsgi --stop /data/www/wms_project/conf/uwsgi.pid
# 进程守护参数,作用是:当服务进程因「异常原因」退出时,systemd 会自动重启该服务,以此保证服务的高可用性  
Restart=on-failure  
# 重启间隔时间参数,默认0.1秒
RestartSec=5  

[Install]
WantedBy=multi-user.target
EOF


# 授权
sudo chown -R www:www /data/www
sudo chmod -R 755 /data/www
chmod 755 /etc/systemd/system/uwsgi_wms_project.service

# 配置好后下面是运维命令
# 重新加载systemd配置
systemctl daemon-reload

# 开机自启
systemctl enable uwsgi_wms_project

# 启动服务
systemctl start uwsgi_wms_project

# 查看状态
systemctl status uwsgi_wms_project

# 停止服务
systemctl stop uwsgi_wms_project

# 重启服务
systemctl restart uwsgi_wms_project
2.4、Nginx 配置

在www用户下配置nginx

su - www

1、编辑nginx配置文件
mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak

cat > /usr/local/nginx/conf/nginx.conf <<EOF
user www;  
worker_processes auto;   # 启动的工作子进程数量,auto表示和cpu核数一致

pid /usr/local/nginx/logs/nginx.pid;

events {
      worker_connections  1024;
}

http {
      include       mime.types;
      default_type  application/octet-stream;

      # 字符集
      charset utf-8;

      # 客户端上传文件大小限制
      client_max_body_size 100M;

      server {
            listen 80;       # http端口,也可以自定义端口,如1000
            server_name your_domain.com 192.168.1.100;  # 你的域名/服务器IP,多个域名 / IP 用空格分隔,不支持网段
          
            # 网段访问,拒绝所有其他IP
            # allow 192.168.1.0/24;  # 支持 CIDR 网段格式(/24=/255.255.255.0)
            # deny all;              # 拒绝除上述网段外的所有IP

            ##### 以下是自己部署用,只有ip,且不限制访 ###########
            # 1. 监听80端口,设为默认服务器(匹配所有未被其他server块接管的请求)
            listen 80 default_server;
            # 2. server_name 配置为通配符/空值(匹配所有Host头,包括直接用IP访问的情况)
            server_name _;  # 官方推荐的“匹配所有”写法,替代空字符串 ""
            
            # 3. 允许所有IP访问(默认就是允许,显式配置更清晰,避免误加限制)
            allow all;
            # (如果之前配过deny all,务必删掉,否则会冲突)
            ##### 以上是自己部署用,只有ip,且不限制访 ###########


            # 日志
            access_log /usr/local/nginx/logs/nginx_access.log;
            error_log /usr/local/nginx/logs/nginx_error.log;

            # 托管静态文件(核心:Nginx直接处理,不经过uWSGI)
            location /static/ { # /static/ 对应 Django 的 STATIC_URL
                alias /data/www/wms_project/staticfiles/;  # 指向STATIC_ROOT
                expires 30d;  # 缓存30天
                add_header Cache-Control "public";   # 配合 expires,缓存规则:公开缓存(浏览器本地缓存、CDN、代理服务器)
            }

            # 托管媒体文件
            location /media/ { # /media/ 对应 Django 的 STATIC_URL
                alias /data/www/wms_project/media/;   # 指向MEDIA_ROOT
                expires 7d;
                add_header Cache-Control "public";
            }

            # 反向代理到uWSGI(动态请求)
            location / {
                uwsgi_pass unix:/data/www/wms_project/conf/uwsgi.sock;  # 与uWSGI的socket路径一致
                include /usr/local/nginx/conf/uwsgi_params;                    # 加载uWSGI参数(Nginx默认提供),这个是nginx中uwsgi_params的路径
                uwsgi_read_timeout 300;   # Nginx 与 uWSGI 通信的超时指令,单位秒
                
                # 传递请求头(解决Django获取真实IP、域名问题),即透传功能
                uwsgi_param Host $host;
                uwsgi_param X-Real-IP $remote_addr;
                uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
                uwsgi_param X-Forwarded-Proto $scheme;
            }

            # 禁止访问隐藏文件(安全)
            location ~ /\.ht {
                deny all;
            }
     }
}
EOF


2、运维命令
#检查配置文件是否有问题
检查 nginx.conf 配置文件及其引用的所有包含文件的语法是否正确,
同时还会验证配置文件中所引用的文件和目录是否存在并且可访问

/usr/local/nginx/sbin/nginx -t

在root用户下执行运维命令

# 启动
/usr/local/nginx/sbin/nginx 

# 重启
/usr/local/nginx/sbin/nginx -s reload

# 停止
/usr/local/nginx/sbin/nginx -s stop

# 优雅的停止  处理完请求后停止
/usr/local/nginx/sbin/nginx -s quit  # -s 是signal


3、配置systemd 服务
cat > /etc/systemd/system/nginx.service << EOF
[Unit]
Description=nginx web service
Documentation=http://nginx.org/en/docs
After=network.target

[Service]
User=root
Group=root
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t 
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF


# 授权
chmod 755 /etc/systemd/system/nginx.service

# 配置好后下面是运维命令
# 重新加载systemd配置
systemctl daemon-reload

# 设置开机自启
systemctl enable nginx

# 启动nginx
systemctl start nginx

# 查看状态
systemctl status nginx

# 重启Nginx
systemctl restart nginx

# 停止nginx
systemctl stop nginx
2.5、安全组/防火墙

如果有防火墙要记得设置或者关闭

三、验证
1、访问 http://你的域名/ 或 http://服务器IP:port/,确认项目正常访问;
注意:有些浏览器强制使用https访问,可以换几个浏览器尝试如果确认部署没问题而又访问不了,也可以打开无痕浏览试试

2、查看日志文件,确认无报错:
# 查看uWSGI日志
tail -f /data/www/wms_project/log/uwsgi.log

# 查看Nginx错误日志
tail -f /usr/local/nginx/logs/nginx_error.log

# 查看Django日志
tail -f /data/www/wms_project/logs/django_error.log

四、项目更新
# 1. 拉取最新代码或者手动上传也可以
cd /data/www/wms_project/
git pull

# 2. 安装新依赖(若有)
pip install -r requirements.txt

# 3. 数据库迁移(企业里面ddl要走数据库工单,不要用应用直接变更)
python manage.py migrate --noinput

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

# 5. 重启uWSGI
systemctl restart uwsgi_your_project
五、配置https访问

以上配置只适用于http访问,如果想配置https访问,还需要继续配置https

# 1、安装Certbot
sudo yum install -y epel-release
sudo yum install -y certbot python3-certbot-nginx # 注意如果你是redhat7,python3-certbot-nginx要改成python2-certbot-nginx

# 2、获取 SSL 证书并自动配置 Nginx,
# -d 指定域名(多个域名用 -d 追加,如主域名+www子域名)
sudo certbot --nginx --nginx-ctl /usr/local/nginx/sbin/nginx --nginx-server-root /usr/local/nginx/conf -d your-domain.com 

    执行后会出现交互提示:
    输入你的邮箱(用于证书到期提醒);
    同意服务条款(选 Y);
    是否共享邮箱(选 N);
    是否强制 HTTP 跳转 HTTPS(选 2,推荐,所有 HTTP 请求自动转 HTTPS)

# 3、验证 nginx配置文件中的HTTPS 配置
Certbot 会自动修改你的 Nginx 配置文件
最终配置会新增以下核心内容(无需手动改,Certbot 已完成,查看下是否正确即可)

server {
            # 1. 监听80端口,设为默认服务器(匹配所有未被其他server块接管的请求)
            # 2. server_name 配置为通配符/空值(匹配所有Host头,包括直接用IP访问的情况)
    server_name djangosun.cn; # managed by Certbot  
            
            # 3. 允许所有IP访问(默认就是允许,显式配置更清晰,避免误加限制)
            allow all;
            # (如果之前配过deny all,务必删掉,否则会冲突)


            # 日志
            access_log /usr/local/nginx/logs/nginx_access.log;
            error_log /usr/local/nginx/logs/nginx_error.log;

            # 托管静态文件(核心:Nginx直接处理,不经过uWSGI)
            location /static/ { 
                alias /data/www/wms_project/staticfiles/;  
                expires 30d;  # 缓存30天
                add_header Cache-Control "public";   
            }

            # 托管媒体文件
            location /media/ { 
                alias /data/www/wms_project/media/;   
                expires 7d;
                add_header Cache-Control "public";
            }

            # 反向代理到uWSGI(动态请求)
            location / {
                uwsgi_pass unix:/data/www/wms_project/conf/uwsgi.sock; 
                include /usr/local/nginx/conf/uwsgi_params;                    
            
                uwsgi_param Host $host;
                uwsgi_param X-Real-IP $remote_addr;
                uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
                uwsgi_param X-Forwarded-Proto $scheme;    
            }

            # 禁止访问隐藏文件(安全)
            location ~ /\.ht {
                deny all;
            }
     

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/djangosun.cn/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/djangosun.cn/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

    server {
    if ($host = djangosun.cn) {
        # http 强制跳转https
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 ;
    server_name djangosun.cn;
    return 404; # managed by Certbot
}

# 4、验证 HTTPS 是否可访问
sudo systemctl restart nginx    # 重启 Nginx 确保配置生效
访问 https://your-domain.com,浏览器地址栏会显示「锁形图标」,说明 HTTPS 生效;
访问 http://your-domain.com,会自动跳转到 https://your-domain.com(验证跳转规则)


# 5、配置证书自动续期(Let's Encrypt 证书有效期 90 天)
# 第一、创建一个专门用于验证的目录,注意一定要在你的静态文件目录下(/data/www/wms_project/staticfiles), 确保路由能被nginx正确找到
sudo mkdir -p /data/www/wms_project/staticfiles/.well-known/acme-challenge
sudo chown -R www:www /data/www/wms_project/staticfiles/.well-known

# 第二、修改你的server块
server {
    
    # -------------步骤 1: 粘贴下面的 location 块-----------------------
    # 专门为 Let's Encrypt 验证请求开的“后门”
    location /.well-known/acme-challenge/ {
        # 使用 alias 将 URL 路径映射到服务器上的实际文件路径
        alias /data/www/wms_project/staticfiles/.well-known/acme-challenge/;
        
        # (可选) 增加一些安全和性能设置
        location ~ /\. {
            deny all;
        }
        access_log off;
        expires -1;
        add_header Pragma "no-cache";
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }
    # ------------步骤 1: 粘贴上面的 location 块-------------

    # 步骤 2: 保留 Certbot 生成的 if 判断和跳转
    if ($host = djangosun.cn) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name djangosun.cn;
    return 404; # managed by Certbot
}


# 测试自动续期命令是否正常(无报错则正常)
sudo certbot renew --dry-run --webroot --webroot-path /data/www/wms_project/staticfiles


# 添加 crontab 定时任务,每月自动检查续期
sudo crontab -e
# 新增以下内容(每天凌晨 2 点检查,需续期则自动续期)
0 2 * * * certbot renew  --quiet --webroot --webroot-path /data/www/wms_project/staticfiles



# 6、关键补充:Django 适配 HTTPS
即使 Nginx 配置了 HTTPS,Django 仍可能识别为 HTTP 请求(导致重定向 / 登录失效),
需在 django配置文件 中添加以下配置:
# 告诉 Django 前端是 HTTPS(Nginx 已传递 X-Forwarded-Proto 头)
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# 强制使用 HTTPS(可选,Django 层面拦截 HTTP 请求)
SECURE_SSL_REDIRECT = True
# Cookie 仅通过 HTTPS 传输(安全)
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# HSTS 配置(强制浏览器后续仅用 HTTPS 访问,有效期 1 年)
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
posted @ 2026-01-05 09:35  有形无形  阅读(20)  评论(0)    收藏  举报