使用 Nginx 部署 Python 項(xiàng)目
今天的目標(biāo)是完成一個(gè) Python Web 項(xiàng)目的線上部署,我們使用最新的 Django 項(xiàng)目搭建一個(gè)簡(jiǎn)易的 Web 工程,然后基于 Nginx 服務(wù)部署該 Python Web 項(xiàng)目。
1. 前期準(zhǔn)備
1.1 安裝虛擬環(huán)境pyenv
首先要知道,使用虛擬環(huán)境逐漸成了 python 項(xiàng)目開(kāi)發(fā)中的一種主流方式。pyenv 可以幫我們生成多個(gè) python 的虛擬環(huán)境,這樣我可以在同一臺(tái)機(jī)器上使用 python2 或者 python3 或者 python3 的不同版本,避免不同項(xiàng)目因?yàn)橐蕾?lài)模塊版本問(wèn)題發(fā)生沖突。只要使用時(shí),切換到那個(gè)具體的版本環(huán)境即可。下面來(lái)看在 CentOS 上如何安裝并使用 pyenv :
# 安裝git
$ yum install git
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
# 安裝 pyenv-virtualenv
$ git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
$ cat ~/.bashrc
...
# 在~/.bashrc最后加上如下3行
export PATH="~/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# 使配置生效
$ source ~/.bashrc
# 查看pyenv的版本
$ pyenv version
# 查看 pyenv 已經(jīng)托管了哪些 python 版本
$ pyenv versions
# 安裝某個(gè)版本的python
$ pyenv install <version>
接下來(lái)我們安裝 python 3.8.1 ,同時(shí)建立一個(gè)以該版本為基礎(chǔ)的虛擬環(huán)境:
# 安裝python 3.8.1版本
$ pyenv install 3.8.1
# 建立一個(gè)虛擬環(huán)境,python版本選擇3.8.1
$ pyenv virtualenv 3.8.1 env-3.8.1
# 激活該虛擬環(huán)境
$ pyenv activate env-3.8.1
# 查看該環(huán)境下python版本
$ python
激活創(chuàng)建的虛擬環(huán)境后,在使用 python 就是3.8.1版本的了,pip 命令也是該虛擬環(huán)境下的命令。所有 pip 安裝的模塊都會(huì)被安裝到該虛擬環(huán)境下,而不是主環(huán)境中。
1.2 創(chuàng)建django項(xiàng)目
接下來(lái),我們通過(guò) django 框架創(chuàng)建一個(gè)簡(jiǎn)單的 web 項(xiàng)目,操作系統(tǒng)是 CentOS 7.6。
# 進(jìn)入虛擬環(huán)境
$ pyenv activate env-3.8.1
# 安裝django 2.2版本
$ pip install django==2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 使用django-admin命令創(chuàng)建項(xiàng)目
$ django-admin startproject test_nginx
$ cd test_nginx
# 創(chuàng)建第一個(gè)應(yīng)用
$ django-admin startapp first
創(chuàng)建 django 的 web 工程和第一個(gè)應(yīng)用后,我們看到工程的結(jié)構(gòu)目錄如下:
為了讓工程順利跑起來(lái),我們需要調(diào)整下工程中數(shù)據(jù)庫(kù)的配置,在 test_nginx/settings.p 中,找到 DATABASES 變量的賦值語(yǔ)句,并修改成數(shù)據(jù)庫(kù)相關(guān)配置,改為使用 mysql 提供數(shù)據(jù)庫(kù)服務(wù),因此我們需要額外準(zhǔn)備一臺(tái)有 mysql 服務(wù)的機(jī)器。具體修改如下圖所示:
最后,我們可以使用命令行啟動(dòng)該 django 服務(wù)了。
# 安裝依賴(lài)
$ yum install mysql-devel
$ pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple
# 首先要生成django系統(tǒng)給我們準(zhǔn)備好的一些數(shù)據(jù)表
$ python manage.py migrate
# 交互式啟動(dòng)django服務(wù)
$ python manage.py runserver 0.0.0.0:8000
執(zhí)行上述指令后的運(yùn)行結(jié)果如下:
訪問(wèn)主機(jī)的8000端口,發(fā)現(xiàn)有報(bào)錯(cuò),如下:
同樣是 test_nginx/settings.py 中的配置問(wèn)題,默認(rèn)是只允許本機(jī)訪問(wèn),要開(kāi)放的話(huà),可以在 settings.py 中的修改 ALLOWED_HOSTS 的賦值,具體如下:
# ALLOWED_HOSTS = []
# 添加*,允許其他主機(jī)訪問(wèn)django服務(wù)
ALLOWED_HOSTS = ['*']
2. 基于 Nginx 完成 Django 工程的部署
2.1 安裝 uwsgi
python web 服務(wù)必須通過(guò) uwsgi 協(xié)議才能進(jìn)行訪問(wèn),因此需要安裝 uwsgi 服務(wù)來(lái)轉(zhuǎn)發(fā) python 的 http 請(qǐng)求。因此,第一步我們要安裝 uwsgi 服務(wù):
# 激活虛擬環(huán)境
$ pyenv activate env-3.8.1
# 安裝uwsgi服務(wù)
$ pip install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple
2.2 使用 uwsgi 啟動(dòng) django 服務(wù)
# 進(jìn)入工程目錄
$ cd /root/test_nginx
$ mkdir uwsgi
# 編輯uwsgi.ini
$ vim uwsgi.ini
$ cat uwsgi.ini
[uwsgi]
# 指定監(jiān)聽(tīng)端口
socket = :8000
# 重要配置
chdir = /root/test_nginx
# 重要,要有wsgi.py文件
module = test_nginx.wsgi
master = true
# 啟動(dòng)進(jìn)程數(shù)
processes = 5
threads = 5
vacuum = true
stats=%(chdir)/uwsgi/uwsgi.status
pidfile=%(chdir)/uwsgi/uwsgi.pid
# 啟動(dòng)uwsgi服務(wù), 使用-d參數(shù)可以放到后臺(tái)運(yùn)行
$ uwsgi -d --ini uwsgi.ini
2.3 配置 nginx ,將請(qǐng)求轉(zhuǎn)發(fā)到 uwsgi 服務(wù)處理
我們?cè)?nginx 中只需要寫(xiě)上一段簡(jiǎn)單的配置,將可以將請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的 uwsgi 服務(wù)上進(jìn)行處理,具體如下:
$ cat /root/nginx/conf/nginx.conf
...
server {
listen 8001;
server_name 127.0.0.1
charset UTF-8;
access_log /var/log/nginx/web_access.log;
error_log /var/log/nginx/web_error.log;
client_max_body_size 75M;
# 最重要的部分
location / {
include uwsgi_params; # 通過(guò)uwsgi轉(zhuǎn)發(fā)請(qǐng)求
uwsgi_pass 127.0.0.1:8000; # 和前面配置django服務(wù)的socket端口保持一致
uwsgi_read_timeout 15; # 設(shè)置請(qǐng)求超時(shí)時(shí)間
}
}
...
重啟 nginx 服務(wù)后,訪問(wèn)8081端口,我們就可以看到前面訪問(wèn)8000端口的結(jié)果了。不同的是,前面是交互式的,使用的是 django 內(nèi)置的 uwsgi 服務(wù)。但是線上環(huán)境,一般不會(huì)這樣去部署 django 服務(wù),而是使用 nginx + uwsgi 配合部署 django web 服務(wù)。
3. 小結(jié)
本節(jié)我們介紹了 python 的虛擬環(huán)境搭建,使用 django 框架創(chuàng)建第一個(gè) web 工程,然后使用 uwsgi 服務(wù)運(yùn)行該 django 項(xiàng)目,最后我們使用 Nginx 服務(wù)將 http 請(qǐng)求轉(zhuǎn)發(fā)到 uwsgi 容器中的 django 工程去執(zhí)行。最后我們從瀏覽器中成功訪問(wèn)了了 django 工程的首頁(yè),這表明著我們部署 django 項(xiàng)目成功。