DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • BBS

  • 订单平台

    • 单点知识
    • 表结构
    • 用户名登陆
    • 短信登陆
    • 菜单和权限
    • 级别管理
    • 客户管理
    • 分页和搜索
    • 价格策略
    • 交易中心
    • message组件
    • 我的交易列表
    • worker
    • 部署之代码同步
    • 部署之线上运行
    • 张sir的部署
      • 本地项目准备
        • 项目下载与测试
        • 在本地让项目跑起来
        • 本地环境:sqlite3数据迁移到MySQL中
        • 本地操作:从MySQL中备份数据库
        • Redis配置
        • 最终调整
      • 线上环境准备
        • 云服务器准备
      • 放开云服务器的安全组
        • 线上:Python3.9.9解释器安装
        • MySQL8.0安装
        • 线上:nginx安装
        • 线上:Redis安装
      • 目录规划
      • 本地项目中配置文件修改为线上的配置并上传项目到云服务器
      • 创建虚拟环境
      • 数据库迁移
      • 测试项目能否运行(重要的一步)
      • 配置uwsgi
      • 静态文件收集
      • 配置nginx
      • ssl配置
        • 域名备案和解析
        • ssl证书申请并上传到服务器
        • nginx中配置证书
      • 让程序实现后台运行
      • 代码优化
      • settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
      • Error 10061 connecting to 82.157.21.45:6379. 由于目标计算机积极拒绝,无法连接。.
      • ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2
      • Invalid HTTPHOST header: '82.157.21.45:8000'. You may need to add '82.157.21.45' to ALLOWEDHOSTS.
  • CRM

  • flask+layui

  • django+layui

  • 供应链

  • 实战
  • 订单平台
DC
2024-05-10
目录

张sir的部署

张sir写的部署过程, 我照搬了过来, 里面涉及到的知识点感觉还挺有用的, 遇到相关问题可以参考下, 哈哈哈!!

# before

部署项目是一个复杂且麻烦的过程:

  • 平台不同,ubuntu、Windows iis、centos7;
  • 项目不同,它依赖的三方软件也不同,要求也不同;
  • 大家的水平也不同,小白的话,有点难;
    • 对于云服务器也不太了解,设置安全组/防火墙;
    • 对于MySQL软件的用户、权限设置不清楚;
  • 对于Linux、云服务器、nginx,都要有了解。
  • 对于查看各种日志不了解;500 ERROR
    • 项目本身在本地都跑不通的这些bug,没有解决的,就上线;
    • 项目开发中,在某些具体功能中把代码写死的,比如连接127.0.0.1的本地开发环境的配置;

务必要记住

  • 本地开发环境,在把项目代码上传到云服务器之前;要在本地进行足够的测试;而且,要把所有连接本地的一些配置,都要改为线上环境的;在项目中,写死的路径、连接,一定要统一的放到配置文件中。d:\xx\xxx\xx.txt
  • 尽量避免出现中文路径和中文文件名。包括一些特殊字符。

# 物料准备

基于centos7 + nginx + mysql + redis + uwsgi + django + ssl + 备案好的域名完成的部署。

所以需要准备:

  • 一个云服务器,配置要求:2核2G内存,带宽,阿里1M;腾讯300M/400M都行;硬盘40G+;系统是cnetos7.x(7.3/7.5/7.6)。
    • 云服务器这块,一般新用户优惠一年100元左右;但如果续费可就不是这个价了。
  • 申请并购买域名,域名和云服务器厂家选择一致就行。
  • 本地要安装xshell、xftp,个人免费版本;
  • 本地准备并调试好你的项目。

# 本地项目准备

# 项目下载与测试

将项目下载到本地,然后创建虚拟环境,并且下载项目依赖包。

# 拉代码到本地
git clone https://gitee.com/wupeiqi/day13

# 终端命令
pip install virtualenv

virtualenv venv
.\venv\Scripts\activate
pip -V
cd day13
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install --no-cache-dir -r requirements.txt
1
2
3
4
5
6
7
8
9
10
11
12

# 在本地让项目跑起来

把项目中所有的数据库连接、或者其他连接本地的,都需要调整为线上环境的。

settings.py

ENVS_ = 'local'
# ENVS_ = 'test'
# ENVS_ = 'pro'


try:
    if ENVS_ == 'local':
    # 放到最后,是为了将前面的覆盖吗
        from .local_settings import *
    elif ENVS_ == 'pro':
        from .pro_settings import *
except ImportError as e:
    print(f'------------> 项目导入{ENVS_}环境配置报错 <------------>', e)
1
2
3
4
5
6
7
8
9
10
11
12
13

pro_settings.py:

# MySQL配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bms',    		#你的数据库名称
        'USER': 'root',   		#你的数据库用户名
        'PASSWORD': '666666', 	#你的数据库密码
        'HOST': '', 			#你的数据库主机,留空默认为localhost
        'PORT': '3306', 		#你的数据库端口
    }
}

1
2
3
4
5
6
7
8
9
10
11
12

local_settings.py:

import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# sqlite3
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# MySQL配置
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.mysql',
#         'NAME': 'bms',    		#你的数据库名称
#         'USER': 'root',   		#你的数据库用户名
#         'PASSWORD': '666666', 	#你的数据库密码
#         'HOST': '', 			#你的数据库主机,留空默认为localhost
#         'PORT': '3306', 		#你的数据库端口
#     }
# }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

访问http://127.0.0.1:8000/login/登录,用户名是root,密码是 qwe123,角色是管理员。

image-20231119101308619

# 本地环境:sqlite3数据迁移到MySQL中

  1. 先根据配置sqlite3的配置文件,生成data.json文件:
import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
1
2
3
4
5
6
7
8

然后执行:

python manage.py dumpdata > data.json
1
  1. 有了data.json文件,把sqlite3的配置文件注释掉,配置上MySQL的配置选项,在local_settings.py中操作:
# -*- coding = utf-8 -*-
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# sqlite3
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#     }
# }

# MySQL配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day13',  # 你的数据库名称
        'USER': 'root',  # 你的数据库用户名
        'PASSWORD': '123',  # 你的数据库密码
        'HOST': "127.0.0.1",  # 你的数据库主机,留空默认为localhost
        'PORT': '3306',  # 你的数据库端口
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  1. 在终端中创建好数据库,再下载pymysql模块,用于和MySQL连接:
# 登录到MySQL中
create database day13 CHARSET utf8mb4 COLLATE utf8mb4_bin;


pip install pymysql

# 然后在settings.py同级目录添加
import pymysql

pymysql.install_as_MySQLdb()
1
2
3
4
5
6
7
8
9
10

关于连接MySQL数据库,用两个模块:

  • mysqlclient,这个模块优先选择,直接pip install mysqlclient下载,然后直接运行项目,如果报任何和mysqlclient的错误。一律不处理。直接改用pymysql。

  • pymysql,pip install pymysql下载,然后再settings.py文件的同级目录找到__init__.py文件,添加如下代码。

    import pymysql
    pymysql.install_as_MySQLdb()
    
    1
    2
  • mysqlclient和pymysql用法一致,只不过pymysql多了一步配置而已,就上面的两行代码。

  1. 执行数据库迁移命令,并根据data.json文件,将数据导入到MySQL的数据库中:
python manage.py makemigrations
python manage.py migrate
python manage.py loaddata data.json  # 执行这个命令肯定报错
1
2
3

报错:

(venv) D:\tmp\od\day13>python manage.py loaddata data.json
Traceback (most recent call last):
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\mysql\base.py", line 75, in execute
    return self.cursor.execute(query, args)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\cursors.py", line 153, in execute
    result = self._query(query)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\cursors.py", line 322, in _query
    conn.query(q)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 558, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 822, in _read_query_result
    result.read()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 1200, in read
    first_packet = self.connection._read_packet()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 772, in _read_packet
    packet.raise_for_error()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.IntegrityError: (1048, "Column 'create_date' cannot be null")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\tmp\od\day13\manage.py", line 22, in <module>
    main()
  File "D:\tmp\od\day13\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\commands\loaddata.py", line 102, in handle
    self.loaddata(fixture_labels)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\commands\loaddata.py", line 163, in loaddata
    self.load_label(fixture_label)
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\commands\loaddata.py", line 253, in load_label
    if self.save_obj(obj):
  File "D:\tmp\od\venv\lib\site-packages\django\core\management\commands\loaddata.py", line 209, in save_obj
    obj.save(using=self.using)
  File "D:\tmp\od\venv\lib\site-packages\django\core\serializers\base.py", line 288, in save
    models.Model.save_base(self.object, using=using, raw=True, **kwargs)
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\base.py", line 877, in save_base
    updated = self._save_table(
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\base.py", line 1020, in _save_table
    results = self._do_insert(
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\base.py", line 1061, in _do_insert
    return manager._insert(
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\query.py", line 1805, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "D:\tmp\od\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1822, in execute_sql
    cursor.execute(sql, params)
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 102, in execute
    return super().execute(sql, params)
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "D:\tmp\od\venv\lib\site-packages\django\db\utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "D:\tmp\od\venv\lib\site-packages\django\db\backends\mysql\base.py", line 75, in execute
    return self.cursor.execute(query, args)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\cursors.py", line 153, in execute
    result = self._query(query)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\cursors.py", line 322, in _query
    conn.query(q)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 558, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 822, in _read_query_result
    result.read()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 1200, in read
    first_packet = self.connection._read_packet()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\connections.py", line 772, in _read_packet
    packet.raise_for_error()
  File "D:\tmp\od\venv\lib\site-packages\pymysql\protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "D:\tmp\od\venv\lib\site-packages\pymysql\err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
django.db.utils.IntegrityError: Problem installing fixture 'D:\tmp\od\day13\data.json': Could not load www.Administrator(pk=1): (1048, "Column 'create_date' cannot be null")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

问题原因,是Administrator模型类中,对于create_date的约束没写全。


class Administrator(ActiveBaseModel):
    """ 管理员表 """
    username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
    password = models.CharField(verbose_name="密码", max_length=64)
    mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
    # create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)
    create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True, null=True, blank=True)  # 添加null=True, blank=True

    def __str__(self):
        return self.username
1
2
3
4
5
6
7
8
9
10
11

然后从新执行:

python manage.py makemigrations
python manage.py migrate
python manage.py loaddata data.json
1
2
3

# 本地操作:从MySQL中备份数据库

有兴趣可以参考:https://www.cnblogs.com/Neeo/articles/11303149.html#普通参数 (opens new window)

mysqldump -uroot -p --default-character-set=utf8 -B 要备份的数据库 >要保存的数据文件名.sql

# 我的项目用到的数据库是day13,所以,我只需要将这一个数据库备份出来即可。
mysqldump -uroot -p --default-character-set=utf8 -B day13 >data.sql
1
2
3
4

备份数据,我不推荐用navicat,因为sql不全,推荐mysqldump命令。

# Redis配置

参考:https://www.cnblogs.com/Neeo/articles/14269422.html (opens new window)

在local_settings.py:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",  # 安装redis的主机的 IP 和 端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "123456"  # redis密码
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

本地测下Redis是否好用。

account.py:

from django.conf import settings
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from www.forms.account import LoginForm, SmsLoginForm, SendSmsForm
from www import models
from django.shortcuts import HttpResponse

from django_redis import get_redis_connection



def login(request):
    # -------------- 新增的代码 -------------------
    conn = get_redis_connection('default')  # 或者显示的使用某个别名

    # 最基本的用法,获取连接对象,并设置值,同时指定过期时间,单位: 秒
    conn.set('18211101111', '8842', ex=10)
    # 在需要的地方在通过连接对象获取值
    print(conn.get("18211101111"))
 	# -------------- 新增的代码 -------------------

    # 1.GET请求看到登录页面
    if request.method == "GET":
        form = LoginForm()
        return render(request, "login.html", {"form": form})

    # 2.用户提交
    # 2.1 是否为空
    form = LoginForm(data=request.POST)
    if not form.is_valid():
        return render(request, "login.html", {"form": form})

    # 2.2 去数据库校验:客户表?管理员表?
    data_dict = form.cleaned_data  # {role:1,username:11,passwrod:123}
    role = data_dict.pop("role")
    if role == "1":
        user_object = models.Administrator.objects.filter(**data_dict).filter(active=1).first()
    else:
        user_object = models.Customer.objects.filter(**data_dict).filter(active=1).first()

    # 2.3 数据不存在
    if not user_object:
        form.add_error("password", "用户名或密码错误")
        return render(request, "login.html", {"form": form})

    # 2.4 数据存在,将用户信息存储session
    mapping = {"1": "ADMIN", "2": "CUSTOMER"}
    request.session[settings.NB_SESSION_KEY] = {
        "role": mapping[role],  # "ADMIN"  "CUSTOMER"
        "id": user_object.id,
        "name": user_object.username,
    }

    # 2.5 成功,跳转后台
    return redirect(settings.HOME_URL)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

浏览器访问login页面,后端打印出来验证码就说明Redis没有问题。

# 最终调整

更新requirements.txt文件,项目根目录终端执行命令:

pip freeze > requirements.txt
1

这样,本地的项目就这样了。

# 线上环境准备

# 云服务器准备

硬件要求:一个云服务器,配置要求:2核2G内存,带宽,阿里1M;腾讯300M/400M都行;硬盘40G+;系统是cnetos7.x(7.3/7.5/7.6)。

选择阿里、华为、腾讯、都可以。我这里以腾讯云为例,演示线上部署。

https://cloud.tencent.com/act

image-20231119112011429

image-20231119112111796

创建远程root账号的密码:

image-20231119112521956

通过xshell连接,下载:https://www.xshell.com/zh/xshell/

image-20231119112742643

image-20231119112757521

image-20231119112825162

服务器有了,执行下面的命令:

# 查看防火墙状态
systemctl status firewalld.service
# 关闭防火墙
systemctl stop firewalld.service
# 禁止开机启动防火墙
systemctl disable firewalld.service
# 启动防火墙
systemctl start firewalld.service
# 防火墙随系统开启启动
systemctl enable firewalld.service
# 关闭selinux,提高了系统的安全性,但关闭它可以释放系统资源,提高服务器的性能,避免一些程序的兼容性问题等等
[root@r ~]# sed -i.ori 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config

systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl status firewalld.service
sed -i.ori 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
yum update -y
yum -y install gcc automake autoconf libtool make
yum -y install net-tools
yum -y install vim
yum -y install wget
yum install lrzsz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 放开云服务器的安全组

image-20231119152301839

# 线上:Python3.9.9解释器安装

Python3.6/Python3.11参考:https://www.cnblogs.com/Neeo/articles/12829625.html#%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85python36

演示cenots7中安装Python3.9,参考:https://www.cnblogs.com/Neeo/articles/12829625.html#%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85python311

yum install -y epel-release
yum update -y
yum install gcc patch libffi-devel python-devel  zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel -y

yum install lrzsz
cd /opt/
wget https://cdn.npmmirror.com/binaries/python/3.9.9/Python-3.9.9.tgz
tar -zxvf Python-3.9.9.tgz
cd /opt/Python-3.9.9
./configure --prefix=/opt/python399/  && make && make install
1
2
3
4
5
6
7
8
9
10

配置环境变量:

echo "export PATH=/opt/python399/bin:$PATH" >> /etc/profile
cat /etc/profile
source /etc/profile

# 添加软连接
ln -s /opt/python399/bin/python3.9 /usr/bin/python3.9
ln -s /opt/python399/bin/pip3.9 /usr/bin/pip3.9
1
2
3
4
5
6
7

任意路径测试:

[root@cs opt]# python3.9 -V
Python 3.9.9
[root@cs opt]# pip3.9 -V
pip 21.2.4 from /opt/python399/lib/python3.9/site-packages/pip (python 3.9)
1
2
3
4

# MySQL8.0安装

https://www.cnblogs.com/Neeo/articles/17135006.html#for-centos7x

把本地的初始sql文件,导入到线上MySQL中:

# 云服务器中执行
# 首先把本地项目根目录下data.sql文件手动上传到云服务器
cd /opt/
mysql -uroot -p123 <data.sql
1
2
3
4

# 线上:nginx安装

代理服务器:

下载依赖

yum update -y
yum -y install gcc gcc-c++ pcre pcre-devel  zlib zlib-devel openssl openssl-devel libxml2-devel libxslt-devel gd-devel GeoIP-devel jemalloc-devel libatomic_ops-devel perl-devel  perl-ExtUtils-Embed
 
#安装Nginx需要先将官网下载的源码进行编译,依赖gcc环境
 
#PCRE是一个perl库,包括perl兼容的正则表达式库。Nginx的http模块使用pcre库来解析正则表达式 
 
#zlib库提供很多种压缩解压缩方式,Nginx使用zlib对http包的内容进行gzip
 
#OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的秘钥和证书封装管理功能及
SSL协议,并提供丰富的应用程序供测试或其它目的使用。Nginx不仅支持http协议,还支持HTTPS协议
(即在SSL协议上传输http)。
1
2
3
4
5
6
7
8
9
10
11
12

下载

去这个链接:https://nginx.org/en/download.html (opens new window)

cd /opt
wget https://nginx.org/download/nginx-1.24.0.tar.gz
ls

[root@cs opt]# ls
nginx-1.24.0.tar.gz
1
2
3
4
5
6

解压

cd /opt
tar -zxvf nginx-1.24.0.tar.gz
1
2

编译安装,我按照方式3走的

注意:nginx的解压目录和编译目录不能是同一文件夹。

方式1:一切都安装默认安装:

cd /opt/nginx-1.24.0
./configure && make && make install

# 这种方式nginx的安装目录为/usr/local/nginx
1
2
3
4

方式2:按照默认编译,并且指定安装目录:

cd /opt
mkdir my_nginx
cd /opt/nginx-1.24.0
./configure --prefix=/opt/my_nginx
1
2
3
4

方式3:编译所有的功能模块,并且指定安装目录:

cd /opt
mkdir my_nginx
cd /opt/nginx-1.24.0
./configure --prefix=/opt/my_nginx \
    --with-threads \
    --with-file-aio \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_xslt_module=dynamic \
    --with-http_image_filter_module=dynamic \
    --with-http_geoip_module=dynamic \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_auth_request_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_degradation_module \
    --with-http_slice_module \
    --with-http_stub_status_module \
    --with-stream=dynamic \
    --with-stream_ssl_module \
    --with-stream_realip_module \
    --with-stream_geoip_module=dynamic \
    --with-stream_ssl_preread_module \
    --with-compat  \
    --with-pcre-jit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

没有报错的情况:

Configuration summary
  + using threads
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/opt/my_nginx"
  nginx binary file: "/opt/my_nginx/sbin/nginx"
  nginx modules path: "/opt/my_nginx/modules"
  nginx configuration prefix: "/opt/my_nginx/conf"
  nginx configuration file: "/opt/my_nginx/conf/nginx.conf"
  nginx pid file: "/opt/my_nginx/logs/nginx.pid"
  nginx error log file: "/opt/my_nginx/logs/error.log"
  nginx http access log file: "/opt/my_nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

接下来进行编译安装:

make -j$(nproc) && make install -j$(nproc)
1

看下安装目录:

cd /opt/my_nginx
ls

[root@cs my_nginx]# ls
client_body_temp  fastcgi_temp  logs     proxy_temp  scgi_temp
conf              html          modules  sbin        uwsgi_temp
1
2
3
4
5
6

在nginx的安装目录中:

  • conf:存放nginx配置文件目录
  • logs:存放nginx日志目录
  • sbin:存放nginx可执行脚本目录
  • html:存放nginx的网站站点,静态资源的目录

知道主要的目录作用,我们也就可以启动nginx了。

cd /opt/my_nginx/sbin
./nginx
ps -ef|grep nginx

[root@cs sbin]# ps -ef|grep nginx
root      39441      1  0 22:37 ?        00:00:00 nginx: master process ./nginx
nobody    39442  39441  0 22:37 ?        00:00:00 nginx: worker process
root      39444  73894  0 22:37 pts/1    00:00:00 grep --color=auto nginx
1
2
3
4
5
6
7
8

浏览器直接访问你的ip地址就可以看到了:

image-20231118224049201

如果想要在任意目录输入nginx即可启动,那还需要配置nginx的环境变量。

配置nginx环境变量

echo "export PATH=/opt/my_nginx/sbin:\$PATH" >> /etc/profile
source /etc/profile
1
2

此时,就可以在任意位置启动nginx了。

配置启动方式

直接nginx命令启动

# 直接输入nginx来启动,但只能首次启动nginx使用,因为重复启动的话,会提示80端口已被占用
nginx

# 查看nginx相关进程
ps -ef | grep nginx

# 查看NGINX监听的端口
netstat -tunlp | grep nginx

# 平滑重启nginx,也就是重新读取nginx的配置文件,而不是重启进程
nginx -s reload

# 确认nginx配置文件是否争取的
nginx -t 
# 停止nginx, 杀死nginx进程
nginx -s stop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

配置systemctl管理nginx

systemd 配置文件说明:

  • 每一个 Unit 都需要有一个配置文件用于告知 systemd 对于服务的管理方式
  • 配置文件存放于 /usr/lib/systemd/system/,设置开机启动后会在 /etc/systemd/system 目录建立软链接文件
  • 每个Unit的配置文件配置默认后缀名为.service
  • 在 /usr/lib/systemd/system/ 目录中分为 system 和 user 两个目录,一般将开机不登陆就能运行的程序存在系统服务里,也就是 /usr/lib/systemd/system
  • 配置文件使用方括号分成了多个部分,并且区分大小写

我们来配置下:

cat >/lib/systemd/system/nginx.service<<EOF
[Unit]
Description=nginx
After=network.target
 
[Service]
Type=forking
ExecStartPre=/opt/my_nginx/sbin/nginx -t -c /opt/my_nginx/conf/nginx.conf
ExecStart=/opt/my_nginx/sbin/nginx -c /opt/my_nginx/conf/nginx.conf
ExecReload=/opt/my_nginx/sbin/nginx -s reload
ExecStop=/opt/my_nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
cat /lib/systemd/system/nginx.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

解释版:

cat >/lib/systemd/system/nginx.service<<EOF
[Unit]     # 记录service文件的通用信息
Description=nginx    # Nginx服务描述信息
After=network.target    # Nginx服务启动依赖,在指定服务之后启动
[Service]    # 记录service文件的service信息
Type=forking    # 标准UNIX Daemon使用的启动方式
ExecStartPre=/opt/my_nginx/sbin/nginx -t -c /opt/my_nginx/conf/nginx.conf
ExecStart=/opt/my_nginx/sbin/nginx -c /opt/my_nginx/conf/nginx.conf
ExecReload=/opt/my_nginx/sbin/nginx -s reload
ExecStop=/opt/my_nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]    # 记录service文件的安装信息
WantedBy=multi-user.target    # 多用户环境下启用
EOF
cat /lib/systemd/system/nginx.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

然后执行如下命令:

pkill nginx
systemctl daemon-reload
systemctl start nginx
systemctl status nginx
systemctl stop nginx
1
2
3
4
5

image-20231119170126936

# 线上:Redis安装

redis安装:https://www.cnblogs.com/Neeo/articles/17609004.html#redis507-for-centos79 (opens new window)

我的配置:

daemonize yes
# 注意,生产中, 千万不要bind 0.0.0.0,不要将Redis暴露到外网环境,防止被人攻击
bind 0.0.0.0
port 6379
pidfile /opt/redis6379/pid/redis6379.pid
logfile /opt/redis6379/logs/redis6379.log

requirepass 1234
1
2
3
4
5
6
7
8

# 线上部署步骤

# 目录规划

mkdir -p /od
cd /od
1
2

# 本地项目中配置文件修改为线上的配置并上传项目到云服务器

settings.py:


# ENVS_ = 'local'
# ENVS_ = 'test'
ENVS_ = 'pro'


try:
    if ENVS_ == 'local':
    # 放到最后,是为了将前面的覆盖吗
        from .local_settings import *
    elif ENVS_ == 'pro':
        from .pro_settings import *
except ImportError as e:
    print(f'------------> 项目导入{ENVS_}环境配置报错 <------------>', e)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

pro_settings.py:

ALLOWED_HOSTS = ["*"]


# 静态文件收集目录
STATIC_ROOT = "/od/allstatic/"

# 先开着调试模式
DEBUG = True
# 云服务器中的MySQL配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day13',    		#你的数据库名称
        'USER': 'zhangkai',   		#你的数据库用户名
        'PASSWORD': '123', 	#你的数据库密码
        'HOST': '82.157.21.45', 			#你的数据库主机,留空默认为localhost
        'PORT': '3306', 		#你的数据库端口
    }
}

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://82.157.21.45:6379",  # 安装redis的主机的 IP 和 端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "1234"  # redis密码
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

手动将项目打包,并且上传到云服务器的/od目录下:

cd /od
unzip day13.zip

[root@cs od]# ls
day13    # 项目目录
day13.zip
1
2
3
4
5
6

# 创建虚拟环境

下载依赖包:

cd /od
pip3 install virtualenv

virtualenv venv
source /od/venv/bin/activate
pip -V
pip install --upgrade pip
pip install uwsgi
pip install -r day13/requirements.txt
1
2
3
4
5
6
7
8
9
cd /od/day13/
python manage.py runserver 0.0.0.0:8000
1
2

# 数据库迁移

在线上操作

之前的步骤做完:

# 云服务器中执行
cd到data.sql文件所在的目录,执行下面的命令
mysql -uroot -p123 <data.sql
1
2
3

# 测试项目能否运行(重要的一步)

云服务器操作

激活虚拟环境之后,通过下面的命令运行Django项目:

cd /od
source /od/venv/bin/activate
pip install -r day13/requirements.txt
cd day13
python3 manage.py  runserver 0.0.0.0:8000
1
2
3
4
5

# 配置uwsgi

创建uwsig.ini文件:

cd /od
mkdir script
mkdir logs
vim script/uwsgi.ini
1
2
3
4

文件内容:

[uwsgi]

# 填写订单项目的根目录
chdir=/od/day13/

# 填写与项目同名的目录,这是个相对路径,主要就是找到其内的wsgi.py这个文件
module=day13.wsgi

# 虚拟环境的根目录,也就是工作目录
home=/od/venv/

# uwsgi的主进程,其他的uwsgi的进程都是这个主进程的子进程,当你kill时,杀掉的也是这个master主进程
master=true

# uwsgi并发时的工作进程的数量,官网的建议是:2 * cup核数 + 1
# 由这几个进程来分摊并发请求
processes=3

# 临时使用http,实际部署时,通过nginx反向代理,就要把http换成socket,这点别忘了改
http=0.0.0.0:8000
# socket=0.0.0.0:8000

# 当服务器退出时,自动删除unix socket文件和pid文件
vacuum=true

# 默认的请求的大小为4096,如果你接收到了一个更大的请求 (例如,带有大cookies或者查询字符串),那么超过4096的限制就会报错invalid request block size: 4547 (max 4096)...skip,所以我们这里提前调整下
# https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Options.html#buffer-size
buffer-size=32768

# uwsgi的日志文件
logto=/od/logs/uwsgi.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

将项目的线上配置pro_settings.py中的debug模式调整为Flase:

# -*- coding = utf-8 -*-

ALLOWED_HOSTS = ["*"]


DEBUG = False

# 云服务器中的MySQL配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day13',    		#你的数据库名称
        'USER': 'zhangkai',   		#你的数据库用户名
        'PASSWORD': '123', 	#你的数据库密码
        'HOST': '82.157.21.45', 			#你的数据库主机,留空默认为localhost
        'PORT': '3306', 		#你的数据库端口
    }
}

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://82.157.21.45:6379",  # 安装redis的主机的 IP 和 端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "1234"  # redis密码
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

运行uwsgi测试:

cd /od
/od/venv/bin/uwsgi --ini ./script/uwsgi.ini
1
2

把uwsig.ini文件的参数调整一下,这个参数取消注释socket=0.0.0.0:8000:

[uwsgi]

# 填写订单项目的根目录
chdir=/od/day13/

# 填写与项目同名的目录,这是个相对路径,主要就是找到其内的wsgi.py这个文件
module=day13.wsgi

# 虚拟环境的根目录,也就是工作目录
home=/od/venv/

# uwsgi的主进程,其他的uwsgi的进程都是这个主进程的子进程,当你kill时,杀掉的也是这个master主进程
master=true

# uwsgi并发时的工作进程的数量,官网的建议是:2 * cup核数 + 1
# 由这几个进程来分摊并发请求
processes=3

# 临时使用http,实际部署时,通过nginx反向代理,就要把http换成socket,这点别忘了改
# http=0.0.0.0:8000
socket=0.0.0.0:8000

# 当服务器退出时,自动删除unix socket文件和pid文件
vacuum=true

# 默认的请求的大小为4096,如果你接收到了一个更大的请求 (例如,带有大cookies或者查询字符串),那么超过4096的限制就会报错invalid request block size: 4547 (max 4096)...skip,所以我们这里提前调整下
# https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Options.html#buffer-size
buffer-size=32768

# uwsgi的日志文件
logto=/od/logs/uwsgi.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

uwsgi相关命令:

# 相对路径启动,指定配置文件启动后端
uwsgi --ini ./uwsgi.ini    # 启动
    # 启动时会生成两个文件,分别为:
    # PID文件 标识这个程序所处的状态
    # SOCK文件  用来和其他程序通信的
uwsgi --stop uwsgi.pid    # 停止
uwsgi --reload uwsgi.ini   # 重置


# 绝对路径启动,就是要找到uwsgi的绝对路径和uwsig.ini的绝对路径
(crmenv) [root@cs crm]# which uwsgi
/opt/crm/crmenv/bin/uwsgi
# uwsig.ini的绝对路径是 /opt/crm/uwsgi.ini

# 所以,绝对路径启动就是下面的样子
/opt/crm/crmenv/bin/uwsgi --ini /opt/crm/uwsgi.ini

# 关闭uwsgi进程,一键杀死所有与uwsgi相关的进程
pkill -9 uwsgi

# 你也可以先过滤出来,在根据pid进行kill
ps -ef |grep uwsgi # 查看进程,找到pid
kill -9 170515 # 杀死对应进程,-9强制 170515=pid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 静态文件收集

将项目的线上配置pro_settings.py中确认是否有如下参数:

STATIC_ROOT = "/od/allstatic/"
1

执行下面的命令:

cd /od
echo "yes"|python3 ./day13/manage.py collectstatic
1
2

# 配置nginx

编辑nginx配置文件:

vim /opt/my_nginx/conf/nginx.conf
1

文件内容:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    

    server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        gzip on;
        gzip_static on;
        gzip_min_length 1k;
        gzip_vary on; 
        gzip_proxied any;
        gzip_comp_level 9;
        gzip_buffers 4 16k;
        gzip_http_version 1.0;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png image/svg+xml;
        # 所有访问80端口的请求,都转发给8000端口的服务器,即uwsgi服务
        location / {
            include uwsgi_params;
            uwsgi_pass 0.0.0.0:8000;
        }
        location /static {
            alias /od/allstatic/;
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

然后平滑重启nginx:

nginx -t 
nginx -s reload
1
2

同时保证uwsgi在运行,然后你就可以浏览器访问了:

image-20231119173040882

# ssl配置

腾讯云ssl配置参考:https://cloud.tencent.com/document/product/400/35244?from_cn_redirect=1 (opens new window)

# 域名备案和解析

网站部署,最好的是要有个备案好的域名,然后让其域名和你的云服务器进行域名解析,这样我们可以通过域名访问我们的云服务器了。

购买域名

购买域名,一般原则是你买个哪个厂家的云服务器,就也买哪个厂家提供的域名。

我之前从阿里云迁移到腾讯云的时候,在阿里那边备案好的域名要迁移到腾讯云,阿里云官网做域名迁出动作,腾讯云官网做域名迁入动作,麻烦!

迁入腾讯云的域名要从新备案,更麻烦。费事,所以,你要整域名的话,要考虑好你用哪个厂家的云服务器,尽量买个久点服务器。

参考:https://buy.cloud.tencent.com/domain

image-20231119173526901

image-20231119173555299

#

域名备案

买完了域名,然后就要去其官网找域名备案功能,备案这个流程顺利的话需要十天半个月的。

你可以在手机上下载云服务器的微信小程序,在小程序上搜索"腾讯云备案小程序",然后开始按提示操作即可。

整个备案过程也是很麻烦的,大概的流程就是填写备案申请。让你提交啥材料你就提交啥材料,然后提交到云服务器厂家审核,有问题的话会有小姐姐电话联系你说你哪里需要修改,然后你就修改之后,继续提交申请,继续审核,然后这个云服务器厂家审核通过了,会给你发短信提醒:

【腾讯云】尊敬的用户,恭喜您提交的(主办单位名称: xxx,备案订单号:3016xxxxxxxxxxxx)备案订单通过腾讯云备案初审,您的备案信息已提交管局审核。管局受理后,备案负责人(xxx)将会收到管局下发短信核验通知,请收到短信后在24小时内按照短信提示登录工信部网站进行短信核验。超时未验证导致备案订单被退回:https://mc.tencent.com/ldERfhrH。审核期间,请勿调整网站内容和域名信息,并保持电话畅通。登录控制台:https://mc.tencent.com/rExpTtQF 。您的账号(账号ID:10001xxxxxx,昵称:xxxxxx)。
1

这个时候,你按照短信提兴去对应的网址上登录短信中的账号和昵称,进行短信验证。

继续等待,因为要把你的备案申请提交到国家工业和信息化部进行审核。这个阶段可能会有电话垂询,问你为啥备案之类的,不过一般良民应该接不到这个电话。

国家工业和信息化部审核通过之后,会给你发短信,由于我在阿里备过案,迁移到腾讯云之后,从新的备的案,所以短信提示是下面这样的。

【工业和信息化部】尊敬的用户xxx,您的备案信息已被变更,详情请咨询您的接入服务提供商。【工信部ICP备案】
1

总之,现在域名备案搞定了.....

总之域名备案是个比较麻烦的步骤,比较费时费力。

微信搜索备案小程序:

image-20231119173957157

然后按照指引进行备案。

域名解析

这一步相当于让域名和你云服务器的公网ID做个映射,让外部访问域名就能解析到你的云服务器公网IP上去。

备案成功之后,登录云服务器控制台,找到域名解析,将备案好的域名和你的服务器进行解析,腾讯云是这个地址:https://console.cloud.tencent.com/cns (opens new window)。

image-20231029160216080

添加域名解析:

image-20231029160240998

解析成功之后,你可以查看一下:

image-20231029160644369

image-20231029160629914

# 我备案好的域名是www.neeo.cc
# 公网IP是82.157.21.45
# 那么腾讯云这边直接给我提供好了两个域名都可以解析到公网IP
# 即www开头的和api开头的都可以
www.neeo.cc
api.neeo.cc

# 如果是阿里云的,如果只有一个www的,那么你可以手动添加一个二级域名,也就是添加一个api的,这个不懂可以百度了
1
2
3
4
5
6
7
8

总之,域名解析完事了

# ssl证书申请并上传到服务器

我这里还是以腾讯云服务器为例,去腾讯云官网申请免费证书,这个地址:https://console.cloud.tencent.com/ssl (opens new window)

image-20231029212630010

我这里申请免费的,有钱大佬请上正式证书。

image-20231029212706990

填写相关信息申请信息。这个ssl证书对应的域名是www.neeo.cc,我们将来给前端用。

image-20231029215109915

等审核,会有短信提示:

【腾讯云】尊敬的腾讯云用户,您购买的域名为 neeo.cc 的 TrustAsia TLS RSA CA 证书(年限:1年,证书ID:9lEHOfy8)现已进入审核验证阶段。请您耐心等待系统自动完成DNS验证,验证通过后证书将会颁发。域名验证方式可参考:https://mc.tencent.com/GhB9OLKA 。登录证书控制台:https://mc.tencent.com/hmpuWwkI 。您的腾讯云账号(账号ID:10xxxxx,昵称:听xxxx)
1

很快的就通过了。

image-20231029215217966

image-20231029215253546

审核通过,也会收到短信通知:

【腾讯云】尊敬的用户,您的域名 neeo.cc 的 TrustAsia TLS RSA CA(1年)证书已审核通过并成功颁发。登录控制台查看证书:https://mc.tencent.com/g9algEWM 。证书部署可参考文档:https://mc.tencent.com/ZKGAc9go 。您的腾讯云账号(账号ID:10xxxxx,昵称:听xxxx)。
1

下载证书:

image-20231029215753125

image-20231029215915200

下载到本地后,直接将压缩包上传到云服务器:

cd /od
unzip neeo.cc_nginx.zip
ls

[root@cs od]# ls
allstatic  day13.zip  neeo.cc_nginx      openssl-1.1.1q         script
day13      logs       neeo.cc_nginx.zip  openssl-1.1.1q.tar.gz  venv
1
2
3
4
5
6
7

# nginx中配置证书

配置参考腾讯云官网:https://cloud.tencent.com/document/product/400/35244?from_cn_redirect=1 (opens new window)

注意,云服务器中的安全组注意放开443端口。

image-20231119180442543

首先要拿到ssl两个文件的绝对路径:

cd /od/neeo.cc_nginx/
ls

# 接下来手动拼接出来这俩绝对路径
/od/neeo.cc_nginx/neeo.cc_bundle.crt
/od/neeo.cc_nginx/neeo.cc.key
1
2
3
4
5
6

编辑nginx的配置文件:

mv /opt/my_nginx/conf/nginx.conf /opt/my_nginx/conf/nginx.conf.bak
vim /opt/my_nginx/conf/nginx.conf
1
2

文件内容。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    
    server {
        #SSL 默认访问端口号为 443
        listen 443 ssl; 
        #请填写绑定证书的域名
        server_name www.neeo.cc; 
        #请填写证书文件的相对路径或绝对路径
        ssl_certificate /od/neeo.cc_nginx/neeo.cc_bundle.crt; 
        #请填写私钥文件的相对路径或绝对路径
        ssl_certificate_key /od/neeo.cc_nginx/neeo.cc.key; 
        ssl_session_timeout 5m;
        #请按照以下协议配置
        ssl_protocols TLSv1.2 TLSv1.3; 
        #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
        ssl_prefer_server_ciphers on;
        gzip on;
        gzip_static on;
        gzip_min_length 1k;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 9;
        gzip_buffers 4 16k;
        gzip_http_version 1.0;
        # 进行压缩的文件类型
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png image/svg+xml;
        # 访问https://www.nee.cc的请求转发给uwsgi
        location / {
            include uwsgi_params;
            uwsgi_pass 0.0.0.0:8000;
        }
        location /static {
            alias /od/allstatic/;
        }
     }

    server {
        listen 80;
        #请填写绑定证书的域名
        server_name www.neeo.cc; 
        #把http的域名请求转成https
        return 301 https://$host$request_uri; 
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

完事之后:

[root@cs neeo.cc_nginx]# nginx -t
nginx: the configuration file /opt/my_nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/my_nginx/conf/nginx.conf test is successful
[root@cs neeo.cc_nginx]# nginx -s reload
1
2
3
4

你的浏览器访问就是https的了。

image-20231119181204144

# 让程序实现后台运行

云服务器上执行

每一次项目代码更新,都可以重新覆盖掉/od,下面的day13项目,然后下面的命令即可。

cd /od
source /od/venv/bin/activate
pip install -r day13/requirements.txt
pkill -9 uwsgi
nohup /od/venv/bin/uwsgi --ini ./script/uwsgi.ini >/dev/null 2>&1 &
1
2
3
4
5

主要用的是nohup命令。

# 代码优化

mysql和Redis都能支持远程访问,肯定是不行的,容易被黑,所以,我们需要设置一下,仅能本地访问,所以,直接调整如下几个文件。

项目的配置文件pro_settings.py:

ALLOWED_HOSTS = ["*"]


STATIC_ROOT = "/od/allstatic/"

# 先开着调试模式
DEBUG = False
# 云服务器中的MySQL配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day13',    		#你的数据库名称
        'USER': 'zhangkai',   		#你的数据库用户名
        'PASSWORD': '123', 	#你的数据库密码
        'HOST': '127.0.0.1', 			#你的数据库主机,留空默认为localhost
        'PORT': '3306', 		#你的数据库端口
    }
}

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",  # 安装redis的主机的 IP 和 端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "1234"  # redis密码
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

redis的配置文件vim /opt/redis6379/conf/redis6379.conf:

daemonize yes
# 注意,生产中, 千万不要bind 0.0.0.0,不要将Redis暴露到外网环境,防止被人攻击
bind 127.0.0.1
port 6379
pidfile /opt/redis6379/pid/redis6379.pid
logfile /opt/redis6379/logs/redis6379.log
requirepass 1234
1
2
3
4
5
6
7

重启Redis服务

pkill -9 redis
redis-server /opt/redis6379/conf/redis6379.conf
1
2

最终,重启uwsgi:

cd /od
source /od/venv/bin/activate
pip install -r day13/requirements.txt
pkill -9 uwsgi
nohup /od/venv/bin/uwsgi --ini ./script/uwsgi.ini >/dev/null 2>&1 &
1
2
3
4
5

在云服务器中的安全组中把uwsgi、mysql和Redis这两个对外的端口禁用掉。

image-20231119183906259

修改uwsgi.ini文件,vim /od/scrit/uwsgi.ini:

[uwsgi]

# 填写订单项目的根目录
chdir=/od/day13/

# 填写与项目同名的目录,这是个相对路径,主要就是找到其内的wsgi.py这个文件
module=day13.wsgi

# 虚拟环境的根目录,也就是工作目录
home=/od/venv/

# uwsgi的主进程,其他的uwsgi的进程都是这个主进程的子进程,当你kill时,杀掉的也是这个master主进程
master=true

# uwsgi并发时的工作进程的数量,官网的建议是:2 * cup核数 + 1
# 由这几个进程来分摊并发请求
processes=3

# 临时使用http,实际部署时,通过nginx反向代理,就要把http换成socket,这点别忘了改
#http=0.0.0.0:8000
# socket=0.0.0.0:8000
# 只能云服务器本地访问
socket=127.0.0.1:8000

# 当服务器退出时,自动删除unix socket文件和pid文件
vacuum=true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

在修改nginx配置文件,主要是uwsgi_pass 127.0.0.1:8000;:

(venv) [root@cs od]# vim /opt/my_nginx/conf/nginx.conf
(venv) [root@cs od]# cat /opt/my_nginx/conf/nginx.conf



#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    
    server {
        #SSL 默认访问端口号为 443
        listen 443 ssl; 
        #请填写绑定证书的域名
        server_name www.neeo.cc; 
        #请填写证书文件的相对路径或绝对路径
        ssl_certificate /od/neeo.cc_nginx/neeo.cc_bundle.crt; 
        #请填写私钥文件的相对路径或绝对路径
        ssl_certificate_key /od/neeo.cc_nginx/neeo.cc.key; 
        ssl_session_timeout 5m;
        #请按照以下协议配置
        ssl_protocols TLSv1.2 TLSv1.3; 
        #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
        ssl_prefer_server_ciphers on;
        gzip on;
        gzip_static on;
        gzip_min_length 1k;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 9;
        gzip_buffers 4 16k;
        gzip_http_version 1.0;
        # 进行压缩的文件类型
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png image/svg+xml;
        # 访问https://www.nee.cc的请求转发给uwsgi
        location / {
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:8000;
        }
        location /static {
            alias /od/allstatic/;
        }
     }

    server {
        listen 80;
        #请填写绑定证书的域名
        server_name www.neeo.cc; 
        #把http的域名请求转成https
        return 301 https://$host$request_uri; 
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

然后将nginx和uwsgi都重新启动下:

cd /od
pkill -9 uwsgi
nohup /od/venv/bin/uwsgi --ini ./script/uwsgi.ini >/dev/null 2>&1 &
nginx -t 
nginx -s reload
1
2
3
4
5

# 常见报错

# settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

windows11 + python3.10 + pycharm2023

配置文件中,数据库的配置参数有误,甚至没有配置,检查settins.py中的数据库连接配置。

# Error 10061 connecting to 82.157.21.45:6379. 由于目标计算机积极拒绝,无法连接。.

本地无法连接远程的Redis服务。

排错思路:

  1. 检查云服务器安全组是否放开6379端口
  2. 检查你项目的Redis配置,否是有误。
  3. 检查云服务器上的Redis配置文件的bind命令是否监听的是bind 0.0.0.0。

注意,以上都动作有调整之后,都要想着重启Redis服务,相关命令。

pkill redis
redis-server /opt/redis6379/conf/redis6379.conf
vim /opt/redis6379/conf/redis6379.conf
1
2
3

# ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2

这个问题是urllib3的版本高,依赖openssl的版是1.1.1+

解决方式有两个:

  • 升级openssl,这个暂时不推荐。
  • 降级urllib3,选择这个。
原来的urllib3的版本是2.0.3,现在降到1.26.15
pip install urllib3==1.26.15
1
2

# Invalid HTTP_HOST header: '82.157.21.45:8000'. You may need to add '82.157.21.45' to ALLOWED_HOSTS.

部署之线上运行
动态菜单

← 部署之线上运行 动态菜单→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式