跳转至

部署

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

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

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

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

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

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

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

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

架构说明

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

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

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

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

  • Django 在生产环境不应该处理静态资源(比如网页、图片等)的请求

前面是开发阶段,为了是环境搭建容易,我们还是让Django来处理静态资源的请求了。

在生产环境不能这样做,这里我们使用Nginx来处理静态资源的请求。

  • Django 在生产环境 不能直接处理 HTTP请求

Django是 wsgi web application 的框架,它只有一个简单的单线程 wsgi web server。 供调试时使用。性能很低。

在生产环境必须提供 专业的 wsgi web server,比如 uWSGI 或者 Gunicorn。 我们这里使用 Gunicorn。

而且即使有了 uWSGI 或者 Gunicorn,我们最好还要在前面设置 Nginx 。所有的客户请求由它先接受,再进行相应的转发。

为什么要这样?

Nginx 在整个后端的最前方, 可以实现 负载均衡、反向代理、请求缓存、响应缓存 、负荷控制等等一系列功能。可以大大的提高整个后端的性能和稳定性。

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

image

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

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

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

  • Nginx

Nginx 运行起来是多个进程,接收从客户端(通常是浏览器或者手机APP)发过来的请求。

它会 根据请求的URL 进行判断:

如果请求的 是 静态资源,比如HTML文档、图片等,它直接从配置的路径进行读取,返回内容给客户端。

如果请求的 是 动态数据, 转发给 Gunicorn+Django 进行处理

  • Gunicorn/Django

Gunicorn 和 Django 是运行在同一个 Python进程里面的。 它们都是用Python代码写的程序。

启动Gunicorn的时候,它会根据配置加载Django的入口模块,这个入口模块里面提供了WSGI接口。

当 Gunicorn 接收到 Nginx 转发的 HTTP请求后,就会调用 Django的 WSGI入口函数,将请求给Django进行处理。

Django框架 再根据请求的URL 和 我们项目配置的 URL 路由表,找到我们编写的对应的消息处理函数进行处理。

我们编写的消息处理函数,就是前面章节大家学习到的,处理前端请求。如果需要读写数据库,就从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_back_v1.5

修改其中 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'
  • 添加 Linux 启动shell脚本

生产环境,我们使用 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.douban.com/simple/

安装 Gunicorn

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

pip3 install greenlet -i https://pypi.douban.com/simple/
pip3 install gevent    
pip3 install gunicorn

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

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

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


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

  • 先使用root用户创建数据库bysms,指定使用utf8的缺省字符编码,执行命令如下
CREATE DATABASE bysms CHARACTER SET utf8mb4  COLLATE utf8mb4_unicode_520_ci;
  • 再创建 bysms系统用来连接数据库的用户,保证该用户有访问 bysms数据库的权限,比如
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.douban.com/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。

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

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况