应用项目部署

应用项目部署

当一个应用项目经过开发人员的努力,完成了需求分析、程序设计、开发、测试,最后一步是把应用程序部署到生产环境中正式上线,也就是把应用程序安装到服务器上,让他人可以访问。本章介绍myproject项目部署到Ubuntu系统服务器的过程。由于系统版本、环境的不同,有些步骤可能略有差异。

准备工作

在开发测试阶段,python manage.py runserver可使Django项目很便捷地在本地运行,但效率低,只允许少量用户访问。在生产环境中的应用系统要考虑系统安全、响应速度、运行效率、静态文件处理、动态页面性能等问题,一般在生产环境部署Django项目的方案大多基于Linux+uWSGI+Nginx组合方式进行部署,本项目采用的Linux操作系统是Ubuntu,使用MySQL数据库。

基本知识

在部署前先了解一下Nginx、uWSGI的相关知识。Nginx是一款轻量级HTTP服务器,它能提供一个负载均衡器和一个HTTP缓存,具有占用内存少、稳定性高、并发服务能力强等优势;最适合处理静态文件,如css文件、js文件、HTML文件、图片文件等,在生产环境中动态文件一般由Nginx转交给uWSGI处理。

uWSGI是实现了uWSGI、WSGI、HTTP等协议的Web服务器,具有超强性能、低内存占用、多应用程序管理、高可定制性等优势。在生产环境中,uWSGI可作为Nginx服务器部署的补充选项,它相当于一个中间桥梁,Nginx服务器通过HttpUwsgiModule模块与uWSGI服务器进行数据交换,uWSGI服务器通过在配置文件中指定application的地址能直接和应用框架(如Django)中的WSGI application通信。

我们部署的系统架构如图,这个架构充分利用Nginx服务器和uWSGI服务器各自的优势,静态文件由Nginx服务器处理,动态文件由uWSGI和应用程序共同处理。

由浏览器根据HTTP协议发送请求给Nginx服务器,Nginx服务器从请求中分出对静态文件请求的部分进行处理,把对动态文件请求部分通过Socket接口传给uWSGI服务器,由uWSGI服务器和Django应用程序共同对动态文件请求进行处理,两者之间用WSGI协议进行数据交换,处理完后把响应结果通过Socket接口传给Nginx服务器,由Nginx服务器把响应结果通过HTTP协议传给浏览器,由浏览器对页面进行渲染呈现给用户。

安装环境环境简介

我们在Ubuntu上安装部署应用项目,安装环境的操作系统是Ubuntu 18.04.3 LTS、Nginx 1.14.0、uWSGI 2.0.18、Python 3.6.8、Django 2.1.4、虚拟环境为virtualenv 16.7.7、数据库为MySQL 5.7.27。

准备工作

Ubuntu把系统管理员root收起,禁止了root直接登陆。系统默认使用操作系统安装过程建立的用户进行登录,这个用户是系统使用者级别的。需要进行系统管理时,只需通过sudo-i命令,再输入密码后就可以使用root权限进行系统管理。切换到管理员的命令如下。

zzd@zzd-virtual-machine:~$ sudo -i
[sudo] zzd 的密码: 
root@zzd-virtual-machine:~# 

第一条命令发出后,系统提示输入本用户的密码,看到命令提示符由$变成#,说明用户已拥有root权限。

退出root权限使用logout命令。

root@zzd-virtual-machine:~# logout
zzd@zzd-virtual-machine:~$ 

然后也可以用sudo后面加命令的方式进行系统管理,以下命令以系统管理员的身份重启MySQL数据库服务。

zzd@zzd-virtual-machine:~$ sudu service mysql restart

在部署前最好先更新一下系统,避免因为版本太旧而给后面的安装软件过程带来麻烦,运行下面的两条命令进行系统更新。

zzd@zzd-virtual-machine:~$ sudo apt-get update
zzd@zzd-virtual-machine:~$ sudo apt-get dist-upgrate

操作系统Ubuntu的/etc/apt/source.list中的源可能较旧,更新一下:

zzd@zzd-virtual-machine:~$ sudo apt-get -y update

更新一下Python安装工具

zzd@zzd-virtual-machine:~$ sudo apt-get install python-setuptools

安装MySQL数据库

安装数据库命令:

sudo apt-get install mysql-server

对数据库进行安全配置,主要针对数据库密码:

sudo mysql_secure_installation

配置数据库

进入MySQL数据库配置文件所在目录,用vim修改my.cnf:

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
# 配置客户端
[client]
# 设置端口号
port = 3306
# 配置Socket
socket = /var/lib/mysql/mysql.sock
# 配置字符集
default-character-set = utf8
# 配置服务端
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
character-set-server=utf8
[mysql]
# 禁用MySQL命令自动补全功能
no-auto-rehash
default-character-set=utf8

说明:

MySQL有两种连接方式:TCP/IP和Socket。当在同一台计算机连接数据库时,用mysql.cock发起连接,无需定义连接计算机的具体IP,设置为空或localhost即可。mysql.sock是随每一次MySQL服务器启动生成的,即使在my.ini或my.cnf中就可以改变IP和端口,重启MySQL时,mysql.sock会重新生成一次,信息将跟着改变,不会影响连接。

设置auto-rehash会开启MySQL命令自动补全功能,MySQL命令行自带这个功能,但是默认是禁用的。如果启用该功能,打开配置文件找到no-auto-rehash,用符号#将其注释,另外增加auto-rehash即可。

安装完数据库后配置一下权限,让系统用户不通过sudo命令就可以使用和管理MySQL:

sudo chmod 775 /var/lib/mysql

重启数据库让配置生效:

sudo service mysql restart

登录命令如下,如果能正常登录说明数据库安装成功。

sudo mysql -uroot -p

生成项目数据库

查看myproject项目的settings文件,可以看到数据库的名字与配置:

DATABASES = {
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # }
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'NAME': 'mytest',
        'USER': 'root',
        'PASSWORD': 'root',
    }
}

根据settings中的配置进入MySQL数据库管理页面,用以下命令生成myproject项目的数据库:

create database mytest default character set utf8 collate utf8_general_ci;

Python环境部署

查看Ubuntu版本的命令:

zzd@zzd-virtual-machine:~$ cat /etc/issue
Ubuntu 20.04.2 LTS \n \l

查看Python版本:

zzd@zzd-virtual-machine:~$ python3 -V
Python 3.8.10

这是操作系统默认安装的Python。

升级pip:

因为使用默认的pip源下载的速度很慢,最好换成阿里云,在用户根目录下新建.pip目录,在该目录下新建pip.conf文件:

zzd@zzd-virtual-machine:~$ sudo mkdir ~/.pip
zzd@zzd-virtual-machine:~$ sudo vim ~/.pip/pip.conf

加入以下内容:

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

安装uWSGI服务器

安装一个uWSGI服务器需要一个C编译器,并且需要安装gcc:

zzd@zzd-virtual-machine:~$ sudo apt-get install gcc

安装uWSGI过程中需要编译,需先安装Python开发相关工具模块:

zzd@zzd-virtual-machine:~$ sudo apt-get install python3-dev

安装uWSGI的命令如下,注意这里利用的是pip:

zzd@zzd-virtual-machine:~$ sudo pip install uwsgi

运行uWSGI以测试安装是否成功:

zzd@zzd-virtual-machine:~$ uwsgi

测试uWSGI:

建立一个test.py文件,输入:

#-*-coding:utf-8-*-
def application(env,start_response):
    start_response('200 OK',[('Content-Type','text/html')])
    return [b'welcome,welcome!']

在测试前,我们先查看服务器的IP地址:

zzd@zzd-virtual-machine:/etc/mysql$ sudo ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    # 这里
        inet 192.168.26.128  netmask 255.255.255.0  broadcast 192.168.26.255
        inet6 fe80::f5ac:fdf:b75f:91ab  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:23:12:04  txqueuelen 1000  (以太网)
        RX packets 583569  bytes 867392769 (867.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 250425  bytes 16267428 (16.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (本地环回)
        RX packets 1135  bytes 109278 (109.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1135  bytes 109278 (109.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在命令行输入,指定HTTP协议端口号为9000,启动的文件为test.py:

zzd@zzd-virtual-machine:~$ sudo uwsgi --http :9000 --wsgi-file test.py

在浏览器输入http://192.168.26.128:9000/有页面显示说明安装正确。

安装Nginx服务器

在服务器上安装Nginx用来处理静态文件:

zzd@zzd-virtual-machine:~$ sudo apt-get install nginx

测试Nginx:

Nginx服务器默认端口号是80,我们重启Nginx服务器然后进行测试:

zzd@zzd-virtual-machine:~$ sudo service nginx start

浏览器输入http://192.168.26.128/可以看到测试页面。

项目部署前的工作

修改项目配置

在settings中加入以下配置:

STATIC_ROOT = os.path.join(BASE_DIR,'/static/')

STATIC_ROOT指明了静态文件的收集目录,这里设置收集目录为项目根目录(BASE_DIR)下的static文件夹。

为了安全起见,在生产环境中需要关闭DEBUG选项以及设置允许访问的域名。打开settings文件,找到DEBUG和ALLOWED_HOSTS这两个选项,将他们设置成如下的值。

DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1','localhost','192.168.26.128','*']

在每个应用程序的migrations文件夹下,把以数字开头的文件都删除。

将项目用到的静态文件复制到项目根目录下的static文件夹中,在命令行终端输入以下命令进行复制,这一步很重要,在后面的Nginx配置中会用到这个静态文件的目录。

python manage.py collectstatic

在项目开发中我们会导入一些第三方python库,为了方便在服务器上一次性安装,我们将项目中导入的第三方Python库的名字写入requirements.txt文本文件:

pip freeze>requiredments.txt

服务器上的目录设置

我们在服务器设置如下目录结构。

/home/zzd
	myweb/
    	myproject/
        myenv/

项目代码上传

通过以下命令建立myweb目录。

zzd@zzd-virtual-machine:~$ mkdir myweb

我们用Xmaneger Enterprise中的Xftp把myproject项目代码传到服务器的myweb目录下。

安装虚拟环境

virtualenv可以搭建虚拟且独立的Python运行环境,使得单个项目的运行环境与其他项目隔离,也就是安装在虚拟环境里的所有软件包均不会对环境外的其他软件包产生影响。反之,在虚拟环境中只能调用虚拟环境中安装的软件包。

安装virtualenv的命令如下:

zzd@zzd-virtual-machine:~$ sudo pip install virtualenv

安装完成后就要建立虚拟目录。进入myweb目录,建立虚拟目录:

zzd@zzd-virtual-machine:~$ cd myweb
zzd@zzd-virtual-machine:~/myweb$ sudo virtualenv --python=python3 myenv

在服务器上配置项目

配置项目时我们先激活虚拟环境:

zzd@zzd-virtual-machine:~/myweb$ source myenv/bin/activate

看到命令提示符前面多了myenv说明已经激活虚拟环境。

接下来就可以安装Django与应用项目用到的第三方Python库,这些可以按照requirements.txt中列出的软件包进行安装:

requirements.txt:

Django==2.1.4
django-ckeditor==5.7.1
django-haystack==2.8.1
django-js-asset==1.2.2
jieba==0.39
Pillow==6.0.0
PyMySQL==0.9.3
pytz==2019.1
Whoosh==2.7.4
(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ sudo pip3 install -r requirements.txt

运行以下两个命令在Ubuntu中MySQL的mytest数据库中创建表.

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ python3 manage.py makemigtations
(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ python3 manage.py migrate

生成Django Admin管理后台的管理员:

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ python3 manage.py createsuperuser

配置Nginx和uWSGI

配置Nginx

首先进入myproject项目根目录,把/etc/nginx/下的uwsgi_params复制到项目根目录下,最后查看该目录下是否有uwsgi_params这个文件:

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ cp /etc/nginx/uwsgi_params
(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ ls

在项目根目录下用sudo vim myproject_nginx.conf建立一个文件:

upstream django{
        server 127.0.0.1:8001;
}
  server {
        # 监听端口号
        listen  8000;
        # 服务器IP或是域名
        server_name 192.168.26.128;
        charset utf-8;
        # Django media
        location /media {
                # 媒体所在文件夹
                alias /home/zzd/myweb/myproject/image;
                }
        location /static {
                # 静态文件所在文件夹
                alias /home/zzd/myweb/myproject/static;
                }
        # 最大上传字节数
        client_max_body_size 75M;

        location / {
                uwsgi_pass  django;
                # uwsgi_params路径,已复制到项目根目录
                include  /home/zzd/myweb/myproject/uwsgi_params;
                }
}

说明:

  • upstream模块主要配置网络数据的接收、处理和转发等内容,这里命名为django,花括号内通过server指定接收、转发的IP和端口,127.0.0.1:8001这个地址与uWSGI的socket设置一致。
  • 在server_name指明提供Nginx的计算机的IP或者是域名。
  • location /static{...}指定所有URL带有/static的请求均由Nginx处理。
  • location / {...}指定其他请求转发给uWSGI处理,由proxy_pass指定处理对象,这里的django就是命名为django的upstream块。

我们在项目根目录下配置完成此文件后需要把这个配置文件加入启用的网站列表中去,使Nginx能使用它。Nginx能启用的网站的目录存放在/etc/nginx/sites-enabled/文件夹下,通过以下命令加入:

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ sudo ln -s myproject_nginx.conf /etc/nginx/sites-enabled/

配置完成后要重启Nginx才能生效:

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ sudo service nginx restart

配置uWSGI

在项目根目录下用sudo vim myproject_uwsgi.ini创建配置文件:

[uwsgi]
# Django根目录,全路径
chdir=/home/zzd/myweb/myproject
# Django项目中wsgi.py文件位置
module=myproject.wsgi
# master = true表示以主进程运行
master = true
# 运行进程数
processes = 10
# 设置socket
socket = 127.0.0.1:8001
chmod-socket = 662
# 退出时清楚Python、Django虚拟环境变量
vacuum = true

测试

启动uWSGI服务器,命令如下:

(myenv) zzd@zzd-virtual-machine:~/myweb/myproject$ uwsgi --ini myproject_uwsgi.ini

浏览器地址栏输入http://192.168.26.128:8000/admin,登录django admin管理后台,打开作者管理页面,输入作者信息、上传头像,不报错则说明部署成功。

posted @ 2021-08-03 21:14  KKKyrie  阅读(295)  评论(0编辑  收藏  举报