0%

Django 项目的部署

规划

使用 nginx + uWSGI + Django + virtualenv + supervisor 发布 web 服务器,如图所示:

部署

Python 3 环境的安装

通过编译源码安装 Python 3。

首先装一些编译源码需要的依赖文件,输入如下命令:

1
yum -y install gcc make cmake zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel

把 Python 安装包上传到 CentOS,然后解压缩:

1
tar -zxvf Python-3.6.5.tgz

创建个目录,用于一会儿安装 Python 3:

指定编译位置到刚才创建的目录

1
./configure --prefix=/usr/local/python3/

编译:

1
make

安装:

1
make install

安装完成。

Django 安装

修改环境变量的配置:

1
vi /etc/profile

将 Python 的安装目录放到环境变量中,比如这样:

保存退出和,执行生效:

1
. /etc/profile

安装基础环境配置:

1
yum groupinstall "Development tools"

安装可能用到的包:

1
yum -y install zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel

指定清华源的下载包,安装 virtualenv,提高速度:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple virtualenv

我们可以升级一下 pip3:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip

安装指定版本的 Django:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cndjango==1.11 

创建一个 Django 站点:

1
2
3
4
5
[root@node01 local]# cd /home
[root@node01 home]# django-admin startproject mysite
[root@node01 home]# ll
总用量 0
drwxr-xr-x 3 root root 35 4月 28 00:45 mysite

修改 Django 项目的配置文件:

1
2
3
[root@node01 mysite]# pwd
/home/mysite/mysite
[root@node01 mysite]# vi settings.py

修改 ALLOWED_HOSTS,使其允许外部访问:

1
ALLOWED_HOSTS = ['*']

0.0.0.0:8080 运行 Django 项目:

1
2
3
[root@node01 home]# pwd
/home
[root@node01 home]# python3 mysite/manage.py runserver 0.0.0.0:8080

项目启动好之后,尝试访问:

virtualenv 虚拟环境

安装 virtualenv:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple virtualenv

可以通过命令找到通过 pip 安装的包所在的位置:

1
2
[root@node01 home]# find /usr/local/python3/ -name site-packages
/usr/local/python3/lib/python3.6/site-packages

创建虚拟环境:

1
2
3
4
5
6
7
8
9
[root@node01 home]# virtualenv --python=python3 venv
created virtual environment CPython3.6.5.final.0-64 in 378ms
creator CPython3Posix(dest=/home/venv, clear=False, global=False)
seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/root/.local/share/virtualenv/seed-app-data/v1.0.1)
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
[root@node01 home]# ll
总用量 0
drwxr-xr-x 3 root root 52 4月 28 00:49 mysite
drwxr-xr-x 4 root root 43 4月 28 00:55 venv

当前目录下多出了个 venv 目录,存放的就是刚刚建立的虚拟环境。

进入虚拟环境 venv 里面的 bin 目录,执行如下,可以进入虚拟环境:

1
2
3
4
[root@node01 bin]# pwd
/home/venv/bin
[root@node01 bin]# . activate
(venv) [root@node01 bin]#

进入虚拟环境后,前面会出现虚拟环境的名字用作提示。

在虚拟环境里安装 Django:

1
(venv) [root@node01 bin]# pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple django==1.11.26

在虚拟环境中创建一个 Django 项目:

1
2
3
4
5
6
7
8
(venv) [root@node01 home]# pwd
/home
(venv) [root@node01 home]# django-admin startproject dj
(venv) [root@node01 home]# ll
总用量 0
drwxr-xr-x 3 root root 31 4月 28 01:00 dj
drwxr-xr-x 3 root root 52 4月 28 00:49 mysite
drwxr-xr-x 4 root root 43 4月 28 00:55 venv

修改刚刚创建的 Django 项目的配置:

1
2
3
(venv) [root@node01 dj]# pwd
/home/dj/dj
(venv) [root@node01 dj]# vi settings.py

设置为允许所有主机访问:

1
ALLOWED_HOSTS = ['*']

运行 Django 项目在 0.0.0.0:8080 端口:

1
2
3
(venv) [root@node01 home]# pwd
/home
(venv) [root@node01 home]# python3 dj/manage.py runserver 0.0.0.0:8080

访问浏览器,可以看到项目顺利启动:

退出虚拟环境:

1
(venv) [root@node01 home]# deactivate

引入项目依赖模块

使用命令导出依赖模块:

1
2
3
4
5
6
7
8
9
10
11
12
[root@node01 home]# pip3 freeze > requirements.txt
[root@node01 home]# cat requirements.txt
appdirs==1.4.3
distlib==0.3.0
Django==1.11
filelock==3.0.12
importlib-metadata==1.6.0
importlib-resources==1.5.0
pytz==2019.3
six==1.14.0
virtualenv==20.0.18
zipp==3.1.0

进入虚拟环境:

1
2
3
4
[root@node01 bin]# pwd
/home/venv/bin
[root@node01 bin]# . activate
(venv) [root@node01 bin]#

把上面提取的文件模块,导入虚拟环境:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r /home/requirements.txt

若出现以下问题,安装它给的版本指定就可以。

uWSGI 安装

往常我们是使用 manage.py 的 runserver 命令启动 Django 项目。但这样运行实际上调用了 Python 内置的 wsgiref 模块,只能单进程单线程运行,效率比较低。

如果使用 uWSGI 启动 Django 项目,可以支持多线程,且稳定效率高。

首先进入到虚拟环境中:

1
2
3
4
[root@node01 bin]# pwd
/home/venv/bin
[root@node01 bin]# . activate
(venv) [root@node01 bin]#

安装 uWSGI,可以指定安装源,加快速度:

1
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple uwsgi

查看 uWSGI 的版本,确定是否安装成功:

1
2
(venv) [root@node01 bin]# uwsgi --version
2.0.18

在项目的根目录中创建并编辑 uwsgi.ini 配置文件:

1
2
3
(venv) [root@node01 mysite]# pwd
/home/mysite
(venv) [root@node01 mysite]# vi uwsgi.ini

在其中写入如下内容,注意修改里面的路径:

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
[uwsgi]

# Django-related settings
# the base directory (full path)
# 项目第一层绝对路径
chdir = /home/mysite
# Django's wsgi file
# 项目第二层相对路径
module = mysite.wsgi
# the virtualenv (full path)
# 指定虚拟环境位置,写虚拟环境第一层绝对路径
home = /home/venv/
# process-related settings
# 主进程
master = true
# maximum number of worker processes
# 代表uwsgi运行的多进程数量,官方建议 2*CPU核数+1
processes = 3
# the socket (use the full path to be safe
# 通过什么访问,后边用nginx,打开socket注释
# socket = 0.0.0.0:8080
http = 0.0.0.0:8080
# ... with appropriate permissions - may be needed
# chmod-socket = 664
# clear environment on exit
# 服务停止时,自动清除pid之类的
vacuum = true

通过 uWSGI,启动项目:

1
2
3
(venv) [root@node01 mysite]# pwd
/home/mysite
(venv) [root@node01 mysite]# uwsgi --ini ./uwsgi.ini

出现如下提示,说明 uWSGI 正常启动:

浏览器访问正常:

退出虚拟环境:

1
2
(venv) [root@node01 mysite]# deactivate
[root@node01 mysite]#

supervisor 安装

supervisor 是一个使用 Python 开发的进程管理工具。supervisor 的作用是,可以用它去启动 uWSGI。当 uWSGI 挂掉的时候,supervisor 会帮助自动重启。另外还可以很方便地管理 uWSGI 进程。

使用 yum 安装 python-setuptools:

1
yum -y install python-setuptools

生成 supervisor 的可执行文件:

1
easy_install supervisor

生成配置到 /etc 目录下:

1
echo_supervisord_conf > /etc/supervisord.conf

编辑刚刚生成的 supervisor 配置文件:

1
vi /etc/supervisord.conf

在文件的最后加入如下内容。注意,第一行修改成自己的虚拟环境所在位置,第二行的 command 根据自己 uWSGI 配置文件所在路径进行修改:

1
2
3
4
5
6
7
[program:mysite]
command= /home/venv/bin/uwsgi --ini /home/mysite/uwsgi.ini ;
autostart=true ;
startsecs=10 ;
autorestart=true ;
stopasgroup=true ;
killasgroup=true ;

启动 supervisor,会自动把 uWSGI 启动:

1
supervisord -c /etc/supervisord.conf

此时可以查看到运行起来的进程:

1
2
3
[root@node01 mysite]# ps aux | grep supervisor
root 25957 0.0 1.0 215536 10100 ? Ss 04:06 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
root 25965 0.0 0.0 112732 972 pts/0 R+ 04:07 0:00 grep --color=auto supervisor

浏览器可顺利访问 Django 项目:

还可以进入 supervisor 的终端控制台:

1
2
3
[root@node01 mysite]# supervisorctl -c /etc/supervisord.conf
mysite RUNNING pid 25958, uptime 0:01:30
supervisor>

控制台里,可以启动或停止你的项目:

1
2
3
4
5
6
7
8
9
10
11
12
supervisor> status mysite    # 查看项目状态
mysite RUNNING pid 25958, uptime 0:02:10
supervisor> stop mysite # 停止项目
mysite: stopped
supervisor> start mysite # 启动项目
mysite: started
supervisor> restart mysite # 重启项目
mysite: stopped
mysite: started
supervisor> exit # 退出 supervisor 控制台

[root@node01 mysite]#

整合 Nginx

在生产环境中,出于安全考量,我们往往不会让用户直接访问项目,而是通过 Nginx 跳转过去,也就是用 Nginx 做反向代理。

修改一下 uWSGI 的配置:

1
vi /home/mysite/uwsgi.ini

将访问方式中,socket 的注释打开,然后注释掉 http:

1
2
socket          = 0.0.0.0:8080
# http = 0.0.0.0:8080

进入 supervisor 控制台,重启项目:

1
2
3
4
5
[root@node01 mysite]# supervisorctl -c /etc/supervisord.conf 
mysite RUNNING pid 25986, uptime 0:40:30
supervisor> restart mysite
mysite: stopped
mysite: started

此时是无法通过浏览器访问到 Django 项目的:

修改 Nginx 的配置:

1
2
3
[root@node01 conf]# pwd
/usr/local/nginx/conf
[root@node01 conf]# vi nginx.conf

注释掉原来的负载均衡相关代码,将 80 端口的访问请求以 uwsgi 的协议代理到 8080 端口:

刷新 Nginx 配置:

1
2
3
4
[root@node01 conf]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node01 conf]# nginx -s reload

直接输入 IP,即可访问到 Django 项目: