Django 项目部署(从0到1)

以下步骤基于 window + CentOS 7.6(云服务器)+ gitee

主要流程

在这里插入图片描述

将项目部署到服务器上的大致流程:

  • 将代码从 本地 上传到 服务器
  • 在服务器上 安装服务、配置环境、获取代码
  • 启动服务

上传代码的方式有很多种,例如:FTP工具、scp命令、rsync服务、svn等,不过目前公司主流的都是使用 git + 代码托管平台

在这里插入图片描述

  • 本地电脑,安装git + git命令 上传代码
  • git 代码托管仓库,创建仓库
  • 远端服务器,安装git + git命令 获取代码

代码管理

  • 代码结构

    # 服务器(部分)
    /data/project/<project_name>/
    	└── <project_name>
    		└── settings.py
    		└── local_settings.py
    		└── wsgi.py
    	└── shell
    		└── <project_name>_uwsgi.ini
    		└── reboot.sh
    		└── stop.sh
    	.gitignore
    	manage.py
    	requirements.txt
    
  • 代码托管仓库

    • 注册 gitee / github

    • 创建仓库(项目)

      只需填写必要信息,不需要勾选其它选项

      # 仓库链接
      https://gitee.com/用户名/仓库名.git
      
  • 本地电脑

    • 安装 git

    • 本地git配置 - 全局

      git config --global user.name "xxx"
      git config --global user.email "xxx@xxx.com"
      
    • gitignore

      .gitignore 文件,写入文件名或文件夹,可以git忽略一些文件,不进行版本控制

      GitHub 的 .gitignore 文件模板集合:https://github.com/github/gitignore

      python 中需要忽略的

      # Byte-compiled / optimized / DLL files
      __pycache__/
      *.py[codz]
      *$py.class
      
      # C extensions
      *.so
      
      # Distribution / packaging
      .Python
      build/
      develop-eggs/
      dist/
      downloads/
      eggs/
      .eggs/
      lib/
      lib64/
      parts/
      sdist/
      var/
      wheels/
      share/python-wheels/
      *.egg-info/
      .installed.cfg
      *.egg
      MANIFEST
      
      # PyInstaller
      #   Usually these files are written by a python script from a template
      #   before PyInstaller builds the exe, so as to inject date/other infos into it.
      *.manifest
      *.spec
      
      # Installer logs
      pip-log.txt
      pip-delete-this-directory.txt
      
      # Unit test / coverage reports
      htmlcov/
      .tox/
      .nox/
      .coverage
      .coverage.*
      .cache
      nosetests.xml
      coverage.xml
      *.cover
      *.py.cover
      .hypothesis/
      .pytest_cache/
      cover/
      
      # Translations
      *.mo
      *.pot
      
      # Django stuff:
      *.log
      local_settings.py
      db.sqlite3
      db.sqlite3-journal
      
      # Flask stuff:
      instance/
      .webassets-cache
      
      # Scrapy stuff:
      .scrapy
      
      # Sphinx documentation
      docs/_build/
      
      # PyBuilder
      .pybuilder/
      target/
      
      # Jupyter Notebook
      .ipynb_checkpoints
      
      # IPython
      profile_default/
      ipython_config.py
      
      # pyenv
      #   For a library or package, you might want to ignore these files since the code is
      #   intended to run in multiple environments; otherwise, check them in:
      # .python-version
      
      # pipenv
      #   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
      #   However, in case of collaboration, if having platform-specific dependencies or dependencies
      #   having no cross-platform support, pipenv may install dependencies that don't work, or not
      #   install all needed dependencies.
      # Pipfile.lock
      
      # UV
      #   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
      #   This is especially recommended for binary packages to ensure reproducibility, and is more
      #   commonly ignored for libraries.
      # uv.lock
      
      # poetry
      #   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
      #   This is especially recommended for binary packages to ensure reproducibility, and is more
      #   commonly ignored for libraries.
      #   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
      # poetry.lock
      # poetry.toml
      
      # pdm
      #   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
      #   pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
      #   https://pdm-project.org/en/latest/usage/project/#working-with-version-control
      # pdm.lock
      # pdm.toml
      .pdm-python
      .pdm-build/
      
      # pixi
      #   Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
      # pixi.lock
      #   Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
      #   in the .venv directory. It is recommended not to include this directory in version control.
      .pixi
      
      # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
      __pypackages__/
      
      # Celery stuff
      celerybeat-schedule
      celerybeat.pid
      
      # Redis
      *.rdb
      *.aof
      *.pid
      
      # RabbitMQ
      mnesia/
      rabbitmq/
      rabbitmq-data/
      
      # ActiveMQ
      activemq-data/
      
      # SageMath parsed files
      *.sage.py
      
      # Environments
      .env
      .envrc
      .venv
      env/
      venv/
      ENV/
      env.bak/
      venv.bak/
      
      # Spyder project settings
      .spyderproject
      .spyproject
      
      # Rope project settings
      .ropeproject
      
      # mkdocs documentation
      /site
      
      # mypy
      .mypy_cache/
      .dmypy.json
      dmypy.json
      
      # Pyre type checker
      .pyre/
      
      # pytype static type analyzer
      .pytype/
      
      # Cython debug symbols
      cython_debug/
      
      # PyCharm
      #   JetBrains specific template is maintained in a separate JetBrains.gitignore that can
      #   be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
      #   and can be added to the global gitignore or merged into this file.  For a more nuclear
      #   option (not recommended) you can uncomment the following to ignore the entire idea folder.
      # .idea/
      
      # Abstra
      #   Abstra is an AI-powered process automation framework.
      #   Ignore directories containing user credentials, local state, and settings.
      #   Learn more at https://abstra.io/docs
      .abstra/
      
      # Visual Studio Code
      #   Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore 
      #   that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
      #   and can be added to the global gitignore or merged into this file. However, if you prefer, 
      #   you could uncomment the following to ignore the entire vscode folder
      # .vscode/
      
      # Ruff stuff:
      .ruff_cache/
      
      # PyPI configuration file
      .pypirc
      
      # Marimo
      marimo/_static/
      marimo/_lsp/
      __marimo__/
      
      # Streamlit
      .streamlit/secrets.toml
      
    • local_settings

      本地:local_settings.py 编写本地特有配置

      线上:local_settings.py 编写线上特有配置(代码上传后需要自行创建)

      .gitignore 中 Django 项目的 local_settings.py 会被忽略

      # Django stuff:
      *.log
      local_settings.py
      db.sqlite3
      db.sqlite3-journal
      
      # settings.py
      编写共同的配置
      try:
      	from .local_settings import *
      except Exception:
      	pass
      
      # local_settings.py
      编写特有的配置(数据库、redis。。。)
      
    • 代码上传

      git remote add origin git@github.com:用户名/仓库名.git  # 添加仓库
      输入密码
      
      # 将密码写入 remote
      git remote remove origin  # 删除原来的 remote
      git remote add origin https://用户名:密码@github.com/xxx/project.git
      
      git add.
      git commit -m "commit message"
      git push origin master
      
  • 服务器

    # 安装 git
    yum install git
    mkdir -p /data/project 	# 新建目录
    cd /data/project  # 进入存放项目的位置
    # 克隆代码(首次)
    git clone https://gitee.com/用户名/仓库名.git
    git clone git@gitee.com:用户名/仓库名.git # 需要SSH密钥
    # 更新代码
    git pull origin master
    
  • 代码版本(补充)

    在本地的 git 每次执行 commit 命令时,都会生成一个提交记录,如果执行git push也会将记录提交到代码仓库。

    各个版本之间进行切换:

    git log 	# 查看目前的提交记录(当前的提交链)
    git reflog 	# 查看所有分支的提交记录(包括分支切换、提交、合并、重置等操作)
    git reset --hard xxx  # 跳转至指定版本
    

    【注】此命令可以在本地、线上执行

密钥

为省去每次 push/pull 代码 都要输入密码,我们将通过密钥简化操作流程,同时为方便操作服务器通过 ssh 工具 + 秘钥 连接服务器

在这里插入图片描述

在本地电脑上利用 SSH + 密钥 连接到远程服务器

ssh 工具
- mac,自带SSH、iTerm2
- win,git集成的ssh、xshell、SecureCRT、FinalShell
  • 本地电脑

    # ssh 工具(Git Bash)
    ssh-keygen -t rsa # 一直按回车直到出现密钥
    cat ~/.ssh/id_rsa.pub # 读取公钥(检验是否已生成)
    ssh-copy-id -i ~/.ssh/id_rsa.pub 用户名@ID # 服务器:用户名@ID
    输入密码登录服务器
    
    # ssh 工具
    >>> ssh 用户名@IP
    >>> 无需密码登录
    # 使用如 FinalShell 等ssh工具,在配置好后不需要输入命令也能直接进行登录
    
  • 服务器

    ssh-keygen -t rsa
    cat ~/.ssh/id_rsa.pub
    
  • 代码托管平台

    设置 -> SSH 公钥
    settings -> SSH and GPG key
    将本地电脑和服务器的公钥分别拷贝进去
    

配置服务器

MySQL

  • 安装服务端 和 客户端

    MariaDB 与 MySQL 同源,但是在云服务上 mysql 可能不好安装上

    yum install mariadb-server -y
    yum install mariadb -y  # 安装 mariadb-server 时,mariadb 被作为依赖安装
    
  • 配置 数据库

    systemctl start mariadb  # 启动
    systemctl stop mariadb   # 停止
    systemctl enable mariadb # 开机启动
    
  • 账号初始化

    • 登录 root

      mysql -u root -p
      
    • root 设置密码(可不设置)

      UPDATE USER SET password=password('123456') WHERE USER='root'; 
      flush privileges;
      
    • 创建用户

      若想要在外部访问服务器,则需要在服务器平台防火墙(安全组),添加 3306 端口的外部访问权限

      -- 创建用户
      CREATE USER 'stars'@'localhost'	IDENTIFIED BY '123456';  -- 只能被本机访问
      CREATE USER 'stars'@'100.100.%' IDENTIFIED BY '123456';  -- 可被外部访问
      flush privileges; -- 更新授权表( INSERT / UPDATE / DELETE )
      
    • 创建数据库

      CREATE DATABASE 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
      SHOW DATABASES;  -- 列出当前用户有权限看到的所有数据库
      
    • 为用户授权

      GRANT ALL PRIVILEGES ON 数据库.* TO stars@'localhost';
      GRANT SELECT, SHOW VIEW ON 数据库.* TO 'read'@'10.0.0.100'; --低权用户
      GRANT CREATE ON *.* TO 'user'@'localhost'; -- 全局级,想建任何库都行
      flush privileges;
      
    • 【补充】

      -- 登录新创建的用户
      mysql -u stars -p -- 默认登录的是 localhost,推荐重新创建一个 'stars'@'localhost'
      mysql -u stars -p -h 127.0.0.1 -- 强制使用 TCP/IP
      
      -- 更新密码
      UPDATE user SET password=password('123456') WHERE user='stars'; 
      flush privileges;
      
      -- 查看所有用户
      select user,host,password from mysql.user;
      +-------+----------------+-------------------------------------------+
      | user  | host           | password                                  |
      +-------+----------------+-------------------------------------------+
      | root  | localhost      |                                           |
      | root  | vm-0-11-centos |                                           |
      | root  | 127.0.0.1      |                                           |
      | root  | ::1            |                                           |
      |       | localhost      |                                           |
      |       | vm-0-11-centos |                                           |
      | stars | 127.0.0.1      | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
      +-------+----------------+-------------------------------------------+
      /*
      mysql 默认配置,在本机中可直接登录数据库无需账户和密码
      若不想数据库可被任意账号登录,则删除匿名用户
      */
      
      -- 删除匿名用户
      DROP USER ''@'localhost';
      DROP USER ''@'vm-0-11-centos';
      flush privileges;
      

Redis

  • 安装

    yum install redis -y
    
  • 配置

    # 打开配置文件
    vim /etc/redis.conf
    # ?查找内容  --  查找
    ?requirepass
    # 'n' --  下一个
    # 'i' --  编辑
    requirepass 123456 # 修改密码
    # 'Esc' -- 退出编辑状态
    # ':wq' -- 保存并退出
    

    目前只能在本机连接,若要外部也能进行连接(MySQL 同理)

    配置文件 -> bind 0.0.0.0
    云服务器 -> 安全组配置 -> 6378端口
    
  • 启动

    systemctl start redis   # 启动
    systemctl restart redis # 重启
    systemctl enable redis	# 开机启动
    

Python3

  • 安装 gcc,用于后续安装Python时编译源码

    yum install gcc -y
    yum groupinstall -y "Development Tools"
    
  • 安装Python3相关依赖

    yum install zlib zlib-devel -y
    yum install bzip2 bzip2-devel  -y
    yum install ncurses ncurses-devel  -y
    yum install readline readline-devel  -y
    yum install openssl openssl-devel  -y
    yum install xz lzma xz-devel  -y
    yum install sqlite sqlite-devel  -y
    yum install gdbm gdbm-devel  -y
    yum install tk tk-devel  -y
    yum install mysql-devel -y
    yum install mariadb-devel -y
    yum install python39-devel -y
    yum install libffi-devel -y
    
  • 下载Python源码,https://www.python.org/ftp/python/

    cd /data/
    wget https://www.python.org/ftp/python/3.9.23/Python-3.9.23.tgz
    

    【注】如果没有wget,则先安装 yum install wget

    【注】直接在官网下载可能会很慢,此时可以选择切换成其它源

  • 编译安装

    • 解压

      tar -xvf Python-3.9.23.tgz
      
    • 进入目录并编译安装

      cd Python-3.9.23
      ./configure
      make all
      make install
      
    • 测试

      python3 --version
      
      /usr/local/bin/python3
      /usr/local/bin/pip3
      /usr/local/bin/pip3.9
      

虚拟环境

  • 安装虚拟环境工具 virtualenv (Python官方社区的工具)

    pip3.9 install virtualenv
    
  • 创建虚拟环境目录 & 创建虚拟环境

    cd /root
    mkdir /envs
    virtualenv /envs/<>env_name> --python=python3.9
    
  • 安装项目依赖的 pip包

    pip freeze > requirements.txt  # 创建项目依赖文件
    git clone https://gitee.com/用户名/仓库.git  # 克隆代码
    
    source /envs/env_name/bin/activate  # 激活虚拟环境
    deactivate  # 退出虚拟环境
    rm -rf /envs/env_name  # 删除虚拟环境
    cd 仓库
    pip install -r requirements.txt # 安装相关的第三方包
    

local_settings 设置线上配置

  • 创建 local_settings

    cd /data/project/<project_name>/<project_name>
    vim local_settings.py
    
  • local_settings.py

    # 指定收集静态文件的位置
    import os
    from pathlib import Path
    BASE_DIR = Path(__file__).resolve().parent.parent
    STATIC_ROOT = os.path.join(BASE_DIR, "allstatic")
    
    DEBUG = False
    ALLOWED_HOSTS = ['*']
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
    		'NAME': 'db',  # 数据库名字
            'USER': 'stars',
            'PASSWORD': '123456', # *
            'HOST': '127.0.0.1',  # ip
            'PORT': 3306,
        }
    }
    
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100},
                "PASSWORD": "123456", # *
            }
        }
    }
    
    # Esc -> :wq
    
  • 收集静态文件

    python manage.py collectstatic --noinput
    

    【注】若静态文件有变动,则需要重新收集

Nginx + uWSGI

为实现 高性能、高并发、稳定部署 的Web服务架构,使用 Nginx + uWSGI

  • Nginx 作为反向代理服务器,负责处理静态资源、负载均衡和SSL终端,提升响应速度和安全性;
  • uWSGI 作为应用服务器,负责运行Python Web应用(如Django、Flask),与Nginx配合实现动态请求的高效处理。

在这里插入图片描述

# 激活虚拟环境并安装 uwsgi + nginx
source /envs/<env_name>/bin/activate
yum install uwsgi -y
yum install nginx -y

shell 脚本

# 先本地操作,之后再上传代码,便于代码管理
/data/project/<project_name>/shell
	└── reboot.sh
	└── stop.sh
	└── django_project<project_name>_uwsgi.ini

uWSGI

  • 命令参数

    # 测试是否可运行,若没问题 ctrl-c 关闭
    uwsgi --http :80 --chdir /data/project/<project_name> --wsgi-file <project_name>/wsgi.py --master --processes 4 --static-map /static=/data/project/<project_name>/allstatic
    
  • 文件参数

    # django_project<project_name>_uwsgi.ini
    [uwsgi]
    socket     = 127.0.0.1:8001  # Nginx + uWSGI 在同一台服务器
    chdir      = /data/project/<project_name>
    home       = /envs/<env_name>/
    module     = <project_name>.wsgi:application
    master     = true
    processes  = 4
    chmod-socket = 666
    vacuum     = true
    enable-threads = true
    static-map = /static=/data/project/<project_name>/allstatic
    
  • reboot.sh

    #!/usr/bin/env bash
    
    echo -e "\033[34m--------------------wsgi process--------------------\033[0m"
    
    ps -ef|grep <project_name>_uwsgi.ini | grep -v grep
    
    sleep 0.5
    
    echo -e '\n--------------------going to close--------------------'
    
    ps -ef |grep <project_name>_uwsgi.ini | grep -v grep | awk '{print $2}' | xargs kill -9
    
    sleep 0.5
    
    echo -e '\n----------check if the kill action is correct----------'
    
    /envs/<env_name>/bin/uwsgi  --ini <project_name>_uwsgi.ini &  >/dev/null
    
    echo -e '\n\033[42;1m----------------------started...----------------------\033[0m'
    sleep 1
    
    ps -ef |grep <project_name>_uwsgi.ini | grep -v grep
    
  • stop.sh

    #!/usr/bin/env bash
    
    echo -e "\033[34m--------------------wsgi process--------------------\033[0m"
    
    ps -ef |grep <project_name>_uwsgi.ini | grep -v grep
    
    sleep 0.5
    
    echo -e '\n--------------------going to close--------------------'
    
    ps -ef |grep <project_name>_uwsgi.ini | grep -v grep | awk '{print $2}' | xargs kill -9
    
    sleep 0.5
    
  • 代码管理

    # 本地
    git add.
    git commit -m "commit message"
    git push origin master
    
    # 服务器
    cd /data/project/<project_name>
    git pull origin master
    
  • 添加权限(在服务器中执行)

    chmod 755 reboot.sh stop.sh
    source /envs/<env_name>/bin/activate
    ./reboot.sh
    

nginx

cd /etc/nginx/
mv nginx.conf nginx.conf.bak  # 备份原本的配置文件
vim nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    # include /etc/nginx/conf.d/*.conf;

	# 反向代理本机端口
    upstream django {
        server 127.0.0.1:8001;  # * 
    }

    server {
        listen       80;
        listen       [::]:80;
        server_name  _; # 域名(server_name.com;)

        # Load configuration files for the default server block.
        # include /etc/nginx/default.d/*.conf;

		# 静态文件 
		location /static {
            alias  /data/project/<project_name>/allstatic/; # *
        }

		# 动态请求
        location / {
            uwsgi_pass  django;
            include     uwsgi_params;
        }

    }
}
systemctl start nginx  # 启动
systemctl enable nginx # 开机启动

域名和解析

  • 申请域名 -> 备案
  • 解析:将域名与服务器 ip 绑定

https

  • SSL证书 -> 免费证书 -> 创建证书

  • 填写申请:绑定域名、验证 。。。

  • 添加 DNS解析记录

  • 下载证书文件 - Nginx

    域名_nginx
    	└── 域名_bundle.pem # 证书文件
    	└── 域名.key # 私钥文件
    
  • 将证书上传到服务器 /data/ssl

  • 修改 nginx 配置(增加对https的支持)

    cd /etc/nginx/
    mv nginx.conf nginx.conf.http.bak  # 备份原本的配置文件
    vim nginx.conf
    
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    
    # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
    include /usr/share/nginx/modules/*.conf;
    
    events {
        worker_connections 1024;
    }
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 4096;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        # Load modular configuration files from the /etc/nginx/conf.d directory.
        # See http://nginx.org/en/docs/ngx_core_module.html#include
        # for more information.
        # include /etc/nginx/conf.d/*.conf;
    
    	# 反向代理本机端口
        upstream django {
            server 127.0.0.1:8001; 
        }
    
        server {
            listen       80;
            listen       [::]:80;
            server_name  <域名>; # 域名
    		rewrite ^(.*) https://$server_name$1 redirect;
    	}
    
        server {
            listen       443 ssl;
            server_name  <域名>; # 域名
    
            ssl_certificate      /data/ssl/<域名>_bundle.pem; # 证书文件
            ssl_certificate_key  /data/ssl/<域名>.key; # 私钥文件
    
            ssl_session_cache    shared:SSL:1m;
            ssl_session_timeout  5m;
            ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers  on;
    
    		# 静态文件 
    		location /static {
                alias  /data/project/<project_name>/allstatic/;
            }
    
    		# 动态请求
            location / {
                uwsgi_pass  django;
                include     uwsgi_params;
            }
    
        }
    }
    
  • 重启

    systemctl restart nginx
    cd /data/project/django-lufei/shell
    ./reboot.sh
    

遇到的问题

  1. 安装 mysqlclient 包时出现的问题

    已安装了相关的依赖但是仍无法安装成功

    解决办法:使用 PyMySQL 作为替代 pip install PyMySQL

    # init.py (与 settings.py 同级)
    import pymysql
    pymysql.install_as_MySQLdb()
    
  2. 运行 uWSGI 出现报错:ImportError: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips'

    urllib3 版本太高,不兼容系统的 OpenSSL 1.0.2

    解决办法:降级 urllib3

    source /envs/Django-LuFei<env_name>/bin/activate
    pip install "urllib3<2" 
    pkill -9 uwsgi
    uwsgi --ini django_project<project_name>_uwsgi.ini &
    
posted @ 2025-11-20 19:51  stars-AI  阅读(0)  评论(0)    收藏  举报  来源