基於騰訊雲CentOS7.4+MySQL5.7+Python3+uWSGI+Nginx的Django項目部署


准備知識

1、django
一個基於python的開源web框架,請確保自己熟悉它的框架目錄結構。

2、uWSGI
一個基於自有的uwsgi協議、wsgi協議和http服務協議的web網關

3、nginx
常用高性能代理服務器

4、wsgi.py
django項目攜帶的一個wsgi接口文件
如果項目名叫mysite的話,此文件就位於[/mysite/mysite/wsgi.py]

項目運行流程 

1、首先客戶端請求服務資源;
2、Nginx作為直接對外的服務接口,接收到客戶端發送過來的http請求,會解包、分析;
3、如果是靜態文件請求就根據Nginx配置的靜態文件目錄,返回請求的資源;
4、如果是動態的請求,Nginx就通過配置文件,將請求傳遞給uWSGI;uWSGI 將接收到的包進行處理,並轉發給WSGI;
5、WSGI根據請求調用Django工程的某個文件或函數,處理完后Django將返回值交給WSGI;
6、WSGI將返回值進行打包,轉發給uWSGI,
7、uWSGI接收后轉發給Nginx,Nginx最終將返回值返回給客戶端(如瀏覽器)。
注:不同的組件之間傳遞信息涉及到數據格式和協議的轉換

說明:

1、第一級的Nginx並不是必須的,uwsgi完全可以完成整個的和瀏覽器交互的流程;
2、在Nginx上加上安全性或其他的限制,可以達到保護程序的作用;
3、uWSGI本身是內網接口,開啟多個work和processes可能也不夠用,而Nginx可以代理多台uWSGI完成uWSGI的負載均衡;
4、django在debug=False下對靜態文件的處理能力不是很好,而用nginx來處理更加高效。

為方便理解,uWSGI,WSGI和uwsgi在網站項目流程圖中的功能如下:(圖片來自博客:https://www.cnblogs.com/new-rain/p/10089941.html

uWSGI,WSGI和uwsgi的區別

(1)WSGI:全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是為 Python 語言定義的 Web 服務器和 Web 應用程序或框架之間的一種簡單而通用的接口。也可以認為WSGI是一種通信協議。自從 WSGI 被開發出來以后,許多其它語言中也出現了類似接口。

WSGI 的官方定義是,Python Web Server Gateway Interface。從名字就可以看出來,這東西是一個Gateway,也就是網關。網關的作用就是在協議之間進行轉換。

WSGI 是作為 Web 服務器與 Web 應用程序或應用框架之間的一種低級別的接口,以提升可移植 Web 應用開發的共同點。WSGI 是基於現存的 CGI 標准而設計的。

WSGI是 Web 服務器(uWSGI)與 Web 應用程序或應用框架(Django)之間的一種低級別的接口

(2)uwsgi:是服務器和服務端應用程序的一種協議,規定了怎么把請求轉發給應用程序和返回;uwsgi是一種線路協議而不是通信協議,在此常用於在uWSGI服務器與其他網絡服務器的數據通信。

(3)uWSGI:是一種 Python Web Server 或稱為 Server/Gateway,uWSGI 是實現了 uwsgi 和 WSGI 兩種協議的Web服務器,負責響應 Python 的 Web 請求。 

因為Apache、Nginx等,它們自己都沒有解析動態語言如 php 的功能,而是分派給其他模塊來做,比如 Apache 就可以說內置了php模塊,讓人感覺好像Apache就支持 php 一樣。 

uWSGI實現了wsgi協議、uwsgi協議、http等協議。 Nginx中 HttpUwsgiModule 的作用是與 uWSGI 服務器進行交換。

一、CentOS7.4自帶Python2安裝Python3

# 查看python的執行位置

which python

# 安裝依賴,使用yum安裝

yum -y groupinstall "Development tools"

yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel

# 下載python3的安裝包

wget -c https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz

# 創建安裝目錄

mkdir /usr/local/python3

# 解壓安裝包

tar -zxvf Python-3.7.0.tgz 

# 進入解壓目錄

cd Python-3.7.0

# 編譯源碼包代碼,--prefix參數,指定稍后源碼包程序的安裝路徑

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

# 生成二進制安裝程序

make

# 運行二進制的服務程序安裝包

make install

注意,在這里可能會報以下錯誤

File "/usr/local/src/Python-3.7.0/Lib/ctypes/__init__.py", line 7, in <module> from _ctypes import Union, Structure, Array ModuleNotFoundError: No module named ‘_ctypes‘ make: *** [install] Error 1

安裝libffi-devel即可解決,yum install libffi-devel,安裝完記得再次運行 make install

安裝成功的界面:

# 創建軟鏈接,安裝完成之后,建立軟鏈接,添加變量,方便在終端中直接使用python3

ln -s /usr/local/python3/bin/python3 /usr/bin/python3

# pip3創建軟鏈接,Python3安裝完成之后pip3也一塊安裝完成,不需要再單獨安裝,一樣建立軟鏈接

ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

# 清理源碼包臨時文件

make clean

# 查看Python3和pip3安裝情況

二、安裝MySQL

安裝的方式使用rpm包方式安裝,要是想用yum安裝見另一篇博客,https://www.cnblogs.com/opsprobe/p/10681063.html

# 下載安裝MySQL

wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar

# 解壓安裝包

tar -vxf mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar

# 查看mysql相關

whereis mysql

# 移除mysql相關的lib(可選項操作,建議操作)

yum remove mysql-libs

#安裝mysql rpm相關的包,相互之見存在依賴關系,按照順序安裝 common --> libs --> clients --> server

rpm -ivh mysql-community-common-5.7.25-1.el7.x86_64.rpm

rpm -ivh mysql-community-libs-5.7.25-1.el7.x86_64.rpm

rpm -ivh mysql-community-client-5.7.25-1.el7.x86_64.rpm

rpm -ivh mysql-community-libs-compat-5.7.25-1.el7.x86_64.rpm

rpm -ivh mysql-community-server-5.7.25-1.el7.x86_64.rpm

下面的截圖是其他機器上用yum安裝時的顯示,可以看到依賴關系:

注意:安裝時可能會報以下錯誤:安裝yum -y install numactl,即可解決

# 這個在后面安裝 msyqlclient 需要依賴的包 rpm -ivh mysql-community-devel-5.7.25-1.el7.x86_64.rpm

# 安裝完成之后,啟動服務

systemctl start mysqld

 

注意: 可能出現警告 [warning: mysql-community-server-5.7.19-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY](https://www.cnblogs.com/royfans/p/7243641.html)

解決方法,安裝時加上命令:rpm -ivh mysql-community-server-5.7.19-1.el6.x86_64.rpm --force --nodeps

 

# 查看服務狀態

systemctl status mysqld

至此MySQL安裝完成

配置MySQL相關:修改MySQL密碼

# 登錄mysql

mysql -u root -p

# 在此時需要密碼,密碼隱藏在log中,查找默認隨機密碼

grep 'password' /var/log/mysqld.log

然后執行 mysql -u root -p ,輸入上面查到的密碼進入,用該密碼登錄后,必須馬上修改新的密碼,不然操作會報如下錯誤:

# 修改密碼,獲取隨機密碼之后,登錄修改密碼(由於mysql密碼策略限制,密碼需要包含大小寫數字,特殊字符)

alter user 'root'@'localhost' identified by 'xxxxx';(或者用 set password=password("youpassword");)

密碼設置太簡單,會報以下錯誤

 這個其實與validate_password_policy的值有關。

validate_password_policy有以下取值:

默認是1,即MEDIUM,所以剛開始設置的密碼必須符合長度,且必須含有數字,小寫或大寫字母,特殊字符。
有時候,只是為了自己測試,不想密碼設置得那么復雜,譬如說,我只想設置root的密碼為123456。
必須修改兩個全局參數:

首先,修改validate_password_policy參數的值

mysql> set global validate_password_policy=0;

validate_password_length(密碼長度)參數默認為8,我們修改為1

mysql> set global validate_password_length=1;

完成之后再次執行修改密碼語句即可成功

mysql> alter user 'root'@'localhost' identified by '123456';

刷新權限

flush privileges;

重新登錄MySQL

mysql -u root -p

 

安裝virtualenv ,建議大家都安裝一個virtualenv,方便不同版本項目管理(pip3安裝的包都在 /data/environment/lab_reports/lib/python3.7/site-packages/ 目錄下)。

pip3 install virtualenv

在這里要是出現如下錯誤提示,就需要更新pip

運行以下命令更新pip,更新pip完成后重新運行命令pip3 install virtualenv

python3 -m pip install --upgrade pip

 

建立軟鏈接

ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv

 

安裝成功在根目錄下建立兩個文件夾,主要用於存放environment和網站文件的。(個人習慣,其它人可根據自己的實際情況處理)

mkdir -p /data/environment

mkdir -p /data/wwwroot

切換到 cd /data/environment/ 下,創建指定版本的虛擬環境。

virtualenv --python=/usr/bin/python3 blog(blog是自定義的)

然后進入cd /data/environment/blog/bin/

啟動虛擬環境:source activate

退出虛擬環境:deactivate

 

留意紅框標記的位置,出現(blog),說明是成功進入虛擬環境。(注意:以下的操作都需要在虛擬環境下進行)

 

安裝Django:

pip3 install django (如果用於生產的話,則需要指定安裝和你項目相同的Django版本)

例如:在Windows下查看Django的版本,如下圖所示,可以看到是2.1.5版本的Django

在服務器上虛擬環境下安裝2.1.5版本的Django

pip3 install django==2.1.5

卸載指定版本 django 的命令

pip3 uninstall django==2.1.5

在本地生成並導出依賴包(導出依賴包的兩種方式,參考自其他博客:https://www.cnblogs.com/clement-jiao/p/9905611.html

# 進入項目目錄,運行以下命令,導出依賴包,我是在PyCharm下操作的

pip3 freeze > requirements.txt

或者:pipreqs ./ --encoding=utf8

# 導出的默認位置就在項目的根目錄下

Django 靜態文件收集

命令:python manage.py collectstatic

運行靜態文件收集命令時,先需要在 settings.py 里配置這個STATIC_ROOT,收集完后,還需要改回來。

注意!!!

它可能會和 STATICFILES_DIRS 沖突,視情況而定。

Django 靜態文件,自強學堂做了很好的說明:https://code.ziqiangxuetang.com/django/django-static-files.html

切換到網站目錄/data/wwwroot,上傳Django項目到這里,包括剛生成的項目依賴文件requirements.txt

安裝依賴包

# 安裝項目依賴(注意:安裝依賴時可能會有錯誤,請百度自行解決)

pip3 install -r requirements.txt

# 接下來需要先在MySQL數據庫里手動新建項目連接的數據庫,然后在項目目錄下,運行下面的命令進行數據庫表的初始化操作

python3 manage.py makemigrations

python3 manage.py migrate

測試運行項目

# 運行項目,0.0.0.0地址為任意客戶端IP都可以訪問,端口自定義

python3 manage.py runserver 0.0.0.0:8000

# 在客戶端的瀏覽器通過服務器的公網地址訪問項目,若能訪問到項目,說明項目部署成功。

Django正常運行之后我們就開始配置uWSGI和nginx,接着還是在虛擬環境里用pip3安裝uWSGI

pip3 install uWSGI

在項目根目錄下創建uwsgi.ini文件,輸入如下內容:

# 指定uwsgi配置
[uwsgi]
# 指定部署項目之后的HTTP訪問,和后面Nginx配置文件里的uwsgi_pass 127.0.0.1:8080處要一致
socket = 127.0.0.1:8080
#http=47.106.218.225:8080(使用uwsgi代理時)
# 指定項目的絕對路徑
chdir=/data/wwwroot/blogs/mysite
# 指定wsgi文件
wsgi-file=mysite/mysite/wsgi.py
# 指定啟動進程數量processes/workers
processes=4
# 指定啟動線程數量
threads=2
# 指定啟動主進程管理
master=true
# 指定存放進程編號的id文件
pidfile=uwsgi.pid
# 指定進程停止時清楚垃圾數據
vacuum=true
# 指定啟用日志記錄(這里指定了uWSGI日志的存儲路徑。)
daemonize=uwsgi.log
# 指定靜態文件映射
#static-map=/static=static_file(使用uwsgi代理時)

:wq 退出,保存

至此,uwsgi+django就完美結合了,但是,光有uwsgi還不夠,uwsgi處理動態請求能力高,但對於靜態請求(如static文件,css,js文件等)處理能力差,此時就要結合nginx一起使用

 

安裝nginx和配置nginx.conf文件(nginx下載地址:http://nginx.org/en/download.html

wget -c http://nginx.org/download/nginx-1.16.0.tar.gz

下載完成后,執行解壓命令:

tar -zxvf nginx-1.16.0.tar.gz

進入解壓后的nginx-1.16.0/目錄:cd nginx-1.16.0/

依次執行以下命令:

./configure

make

make install

make clean

 

nginx一般默認安裝好的路徑為/usr/local/nginx
在/usr/local/nginx/conf/中先備份一下nginx.conf文件,以防意外。

cp nginx.conf nginx.conf-backup

 

然后打開nginx.conf,把原來的內容刪除,直接加入以下內容:

worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 90;    # 我要監聽那個端口
server_name 172.27.0.6;   # 服務器上ifconfig命令查出來的IP地址
charset utf-8;   # Nginx編碼

access_log   /data/wwwroot/blogs/mysite/nginx_access.log;
error_log   /data/wwwroot/blogs/mysite/nginx_error.log;      # access_log和error_log是定義nginx訪問日志和錯誤日志的存放路徑。 


location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;   # 是指uWSGI綁定的監聽地址,端口與原來的uwsgi.ini中設置的端口一致
uwsgi_param UWSGI_SCRIPT mysite.wsgi;
uwsgi_param UWSGI_CHDIR /data/wwwroot/blogs/mysite/;  # 項目的絕對路徑
 }

# 指定靜態文件路徑
location /static/ {
alias /data/wwwroot/blogs/mysite/static/;
}
}
}

這里需要注意的就是項目路徑,一定要寫對,我剛開始就把項目路徑搞錯了,導致花了很多時間去找錯誤。 

 

啟動項目,訪問項目的頁面。(再次提醒,注意:以下操作是在虛擬環境下進行)

進入cd /usr/local/nginx/sbin/目錄

執行 ./nginx -t 命令先檢查配置文件是否有錯,沒有錯就執行以下命令,啟動nginx:

./nginx

終端沒有任何提示就證明nginx啟動成功。

重啟nginx命令:./nginx -s reload(注意:nginx啟動時,才能使用該命令,否則會報錯)

 

進入網站項目目錄

cd /data/wwwroot/blogs/mysite

執行下面命令,通過配置文件啟動:

uwsgi --ini uwsgi.ini

# 停掉uwsig

uwsgi --stop uwsgi.pid

 

以上步驟都沒有出錯的話,就在客戶端瀏覽器里訪問你的項目地址!(服務器的IP地址:nginx的端口號/項目路徑)

如果啟動時就報錯,查看終端信息,解決錯誤。 

如果終端沒有報錯,但是瀏覽時出現500、502等錯誤,就去項目目錄查看nginx日志和uWSGI日志,解決錯誤。

ps aux命令

a:顯示現行終端機下的所有程序,包括其他用戶的程序

u:以面向用戶的格式顯示進程

x:顯示所有程序,不以終端機來區分

# 分別查看系統nginx和uwsgi進程信息

ps aux | grep nginx

ps aux | grep uwsgi

# 強制殺死nginx和uwsgi的進程

killall -9 nginx

killall -9 uwsgi

 

查看python安裝路徑以及pip安裝的包,參考自其它博客:https://blog.csdn.net/mr_cat123/article/details/80435861

CentOS7設置Nginx為開機啟動:參考自博客:https://www.cnblogs.com/xiaojf/p/7891345.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM