部署

点击这里,边看视频讲解,边学习以下内容

我们前面的代码都是在我们自己的电脑(通常是Windows操作系统)上面运行的,因为我们还处于开发过程中。

当我们完成一个阶段的开发任务后,就需要把我们开发的网站服务,给真正的用户使用了。

那就需要我们的 网站 部署在公网机器上,而不是我们的个人电脑。 这个给真正用户使用的网站服务器我们通常称之为 生产环境

通常,我们的web服务是部署在云服务厂商的云主机上,比如阿里云的ECS云主机。当然如果你们公司有自己的机房和公网服务器,当然也可以。

现在的web服务,基本都是采用 Linux 操作系统。 而且生产环境不应该使用 SQLite 数据库,通常是 MySQL、Postgresql、Oracle等。

本章内容就是教大家,如何把基于Django的web系统部署到生产环境,也就是 如何 在Linux操作系统上安装 我们 网站系统,包括我们的代码和MySQL数据库服务。

首先,需要大家有 Linux 和MySQL的 基础知识。如果你还没有掌握,点击这里学习白月黑羽的Linux教程MySQL教程

架构说明

一个大型的网站系统,架构通常非常的复杂,包括很多的功能节点。大家可以以后慢慢学习。

当前,我们先从基础的架构学起。

可能你会说,我们前面已经把网站运行起来了呀,现在只需要把系统从 Windows 转移到Linux上了,把SQLite 改为 MySQL就行了吧?

不仅如此,认真学习课程的同学应该记得,我们前面曾经讲过如下两点:

综上, 我们当前这个简单网站,其架构图如下

这里为了简单,把整个后端系统都部署在同一台Linux主机上,包括:Nginx、Gunicorn、Django(包括我们的代码)、MySQL服务。

在实际项目中,如果系统的负荷比较大,通常是部署在多台主机上。

这个架构的各个子系统是如何协同工作的?

安装步骤

通常,我们的web服务是部署在云服务厂商的云主机上,比如阿里云的ECS云主机,或者企业的IT机房。

这里大家练习的时候,可以先用一台安装了Linux的虚拟机。

我们这里以一台安装了 Ubuntu 的虚拟机为例,给大家演示如何安装部署环境。

大家可以点击这里,根据此教程 先安装好 Ubuntu


安装好后, 为了方便后续apt安装其它软件时,能从国内的apt源高速下载,需要设置一下apt源,具体操作参考我们这篇教程有详细讲解

做好产品发布包

以后当你负责产品发布,你需要准备发布的产品包。

产品的发布包,是不是只是需要把你的代码 用zip打个包?

不是那样简单的。

产品往往会 涉及到好多子系统,前端通常包括 web前端、app前端, 后端 包括 业务处理系统、数据库系统、消息队列、异步任务系统、缓存系统等等。

为了保证这些子系统能在生产环境 友好配合 , 需要仔细的规划、配置、产生发布包。


我们先从基本的做起,我们现在的系统 包括 web前端系统(包括web前端的HTML、css、图片、js业务代码、js库等文件)、后端业务处理系统、数据库系统。

需要做到产品发布包里面的 包括 web前端系统 和 业务处理系统 的代码。

不同的运营架构,部署的方式不同,需要构建发布包的方式也不同。

这里,根据我们的架构图,可以把 前端系统代码 做在一个发布包中, 后端系统做在另一个发布包中。

我们完全可以 把 前后端系统 分别部署到 两台 Linux主机上。当有请求需要Django后端业务系统处理的时候,转发给Django所在的主机即可。 如果请求只是获取一些静态资源,比如HTML、图片等,在前端主机处理完即可。 这样 做到 部署的前后端分离。

目前我们先按照简单的来, 根据我们的架构图, 都部署在同一台机器上。


首先,我们需要为当前版本的发布,准备 web前端发布包,和web后端发布包。

现在我们假定发布的 版本号为 1.5

前端发布包,由前端开发人员提供,在如下百度网盘中的 bysms_front_v1.5.zip,大家先下载到本地

百度网盘链接:https://pan.baidu.com/s/1nUyxvq6IYykBNtPUf4Ho6w

提取码:9w2u


你们作为后端的开发人员,当然由你提供,后端的发布包。

基于Django开发的后端系统,要发布正式版本:

修改其中 bysms/settings.py ,把下面的 配置项DEBUG值为 False

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

前面我们为了开发简单,一直用的SQLite数据库,现在需要改为生产环境的MySQL数据库。

按照如下示例,修改 bysms/settings.py

#DATABASES = {
#   'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#       'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
#}

DATABASES = {
  'default': {
      'ENGINE': 'django.db.backends.mysql',
      'NAME': 'bysms',   # 数据库名
      'USER': 'byhy',    # 数据库 用户名
      'PASSWORD': 'Mima123$',# 数据库 用户密码
      'HOST': '127.0.0.1', # 数据库服务主机名
      'PORT': '3306',      # 数据库服务端口
      'CONN_MAX_AGE': 0
  }
}

当然,上面配置的 MySQL连接的 用户名、密码、数据库名、数据库服务主机名、端口 都要和你的环境匹配。


我们可以在该文件的末尾,加上版本号

VERSION = '1.5'

生产环境,我们使用 Gunicorn 作为 Django的WSGI前端,首先我们需要创建一个 Gunicorn启动配置文件 ./bysms/gunicorn_conf.py ,内容如下

# gunicorn/django  服务监听地址、端口
bind = '127.0.0.1:8000'

# gunicorn worker 进程个数,建议为: CPU核心个数 * 2 + 1
workers =  3 

# gunicorn worker 类型, 使用异步的event类型IO效率比较高
worker_class =  "gevent"  

# 日志文件路径
errorlog = "/home/byhy/gunicorn.log"
loglevel = "info"

import sys,os

cwd = os.getcwd()
sys.path.append(cwd)

要保证我们的Django后端服务在linux上一个命令就能启动,需要开发一个 Linux 启动shell脚本 ./run.sh

可以参考下面的 shell脚本内容

#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
echo $DIR

cd $DIR

# ulimit -n 50000
nohup gunicorn --config=bysms/gunicorn_conf.py bysms.wsgi &> /dev/null &

然后,删除 所有app 的 migrations 目录。


最好把整个Django后端的代码打包,包名为 bysms_back_v1.5.zip

安装、配置 Nginx

大家首先以root 用户 登录Ubuntu主机,

执行命令 apt install nginx 安装好 Nginx


接下来我们需要配置Nginx。

按照上面的安装方式,Nginx的配置文件路径是: /etc/nginx/nginx.conf

当然我们可以使用vim去编辑这个文件,但是建议大家使用 winscp 连接 Linux主机并且,配置用notepad++远程打开。因为这样看起来更清楚,特别是配置文件中如果有中文,vi看起来可能会比较乱。

打开 Nginx 配置文件 /etc/nginx/nginx.conf ,修改其中的配置项,以满足你的网站需求。

下面是一个Nginx配置示例,列出了其中核心的配置

user  byhy;          # 用byhy用户运行Nginx进程
worker_processes  2; # 启动两个Nginx worker 进程

events {
    # 每个工作进程 可以同时接收 1024 个连接
    worker_connections  1024; 
}

# 配置 Nginx worker 进程 最大允许 2000个网络连接
worker_rlimit_nofile 2000;

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

    sendfile        on;

    keepalive_timeout  30;

    gzip  on;
    
    # 配置 动态服务器(比如Gunicorn/Django)
    # 主要配置 名称(这里是apiserver) 地址和端口    
    upstream apiserver  {

        # maintain a maximum of 20 idle connections to each upstream server
        keepalive 20;

        server 127.0.0.1:8000; # 地址和端口
    }
   
    # 配置 HTTP 服务器信息
    server {
        # 配置网站的域名,这里请改为你申请的域名, 如果没有域名,使用IP地址。
        server_name  www.byhy.com;  

        # 配置访问静态文件的根目录,        
        root /home/byhy/bysms_frontend/z_dist;
        
        # 配置动态数据请求怎么处理
        # 下面这个配置项说明了,当 HTTP 请求 URL以 /api/ 开头,
        # 则转发给 apiserver 服务器进程去处理        
        location /api/      {
            proxy_pass         http://apiserver;
            proxy_set_header   Host $host;
        }
    }

}

修改好配置后,必须重启Nginx,可以执行命令

systemctl restart nginx

如果启动报错, 可以打开 /var/log/nginx/error.log 查看nginx的错误日志文件。


为了使http服务的 80端口可以从外部访问,需要我们让防火墙开放80端口。

对于Ubuntu 20 来说,就是执行命令

ufw allow 80

或者 ,下面的命令也行

ufw allow 'Nginx HTTP'

安装 Django

比较简单,执行如下命令

# 这是先安装pip
apt install python3-pip

# 再安装 Django
pip3 install Django -i https://pypi.tuna.tsinghua.edu.cn/simple

安装 Gunicorn

执行下面的命令安装 Gunicorn 和 它依赖的库 gevent 和 greenlet (异步模式需要)

pip3 install greenlet -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install gevent    
pip3 install gunicorn

安装 MySQL,创建数据库和用户

MySQL在Ubuntu上的安装和初始设置 点击这里参考我们的教程

注意:教程中有 修改 mysql 绑定所有网络接口的设置, 如果你的机器是生产环境,通常不要这样做。


安装 好MySQL 服务后,执行 mysql 启动客户端 :

CREATE DATABASE bysms CHARACTER SET utf8mb4  COLLATE utf8mb4_unicode_520_ci;
CREATE USER 'byhy'@'localhost' IDENTIFIED BY 'Mima123$';
CREATE USER 'byhy'@'%' IDENTIFIED BY 'Mima123$';

随后输入如下命令,赋予byhy 用户所有权限,就是可以 该DBMS系统上 访问所有数据库里面所有的表

GRANT ALL ON *.* TO 'byhy'@'localhost';
GRANT ALL ON *.* TO 'byhy'@'%';

安装 MySQL 客户端库

执行 下面两个命令分别安装 MySQL 客户端开发库 和 Python 绑定库 mysqlclient

apt install libmysqlclient-dev  
pip3 install mysqlclient  -i https://pypi.tuna.tsinghua.edu.cn/simple

创建产品运行用户

通常我们需要为运行产品进程,比如 Nginx work进程、Gunicorn 等,创建一个专门的用户。

这里我们使用byhy用户

执行命令创建用户 adduser byhy

安装产品发布包

以root以后登录,执行如下命令安装工具:dos2unix 、unzip

apt install dos2unix
apt install unzip

然后再以 byhy用户 登录Linux 主机,下载拷贝 前端、后端 发布包 bysms_front_v1.5.zipbysms_back_v1.5.zipbyhy 用户home目录下面,也就是 /home/byhy

实际项目中,发布包如果不能直接wget下载,可以使用 winscp 拷贝到 Linux 主机上。

然后执行下面的命令进行解压。

unzip bysms_front_v1.5.zip
unzip bysms_back_v1.5.zip

为了让Django认为你使用的虚拟机的IP地址或者域名是允许使用的, 需要修改settings.py 里面的配置项ALLOWED_HOSTS,加上一个你当前虚拟机的IP,也可以使用 '*' , 表示所有IP都可以。

ALLOWED_HOSTS = ['*','localhost','127.0.0.1']

然后进入到 目录 bysms_back_v1.5 中,

执行命令,让启动脚本符合linux文本格式,并且有可执行权限

dos2unix run.sh
chmod +x run.sh

创建数据库表

执行下面的命令, 让Django 在数据库中 创建 你的系统所需要的表

python3 manage.py makemigrations <your_app_label>
python3 manage.py migrate 

注意, <your_app_label> 需要替换成你的 Django 项目中的 app (只需要写包含了数据库表定义的App)的名字,可以是多个app,中间用空格隔开


开始我们要创建数据库的业务管理员账号,进入到manage.py所在目录,执行如下命令,

python3 manage.py createsuperuser

依次输入你要创建的管理员的 登录名、email、密码。

Username (leave blank to use 'byhy'): byhy
Email address: byhy@163.com
Password:
Password (again):
Superuser created successfully.

启动 Gunicorn/Django

进入到 byhy 用户home目录,执行命令 run.sh

然后,执行命令 ps -ef | grep python |grep gunicorn_conf |grep -v grep 查看 是否启动成功。

自动化部署

上面的过程是不是很麻烦?

一个成熟的产品团队,通常可以开发自动化部署软件。可以一键部署,大大提高效率。

具备了Python开发能力的你,自己就可以尝试开发 自动化部署程序哦。

HTTPS 服务

这里,我们的服务运行在80端口上,是不加密的网站服务。

以后,为了安全考虑,需要运行在HTTPS协议上。

这就需要我们申请证书,并且配置Nginx 使用HTTPS。

以后我们的教程会补充这方面的内容。

作业和练习

根据教程,在阿里云主机,或者虚拟机上,安装 白月医疗系统。

安装成功后,浏览器打开该网站服务,验证可以正确访问。