CentOS 下用 Nginx 和 uwsgi 部署 flask 專案

EyEder發表於2016-01-12

前一陣自己用flask框架寫了一個部落格程式,寫完之後想部署到伺服器上,因為是小白,所以自己google了好些資料,講的零零碎碎而且有些地方只是告訴你怎麼配置,但具體為什麼這樣配卻沒有說明,所以自己總結了一篇從頭到尾的過程。

伺服器上部署專案說白了就是讓你的專案在這臺伺服器上執行並且做到可以在公網上訪問你的專案。
那麼如果要做到這兩點,需要做的工作有如下幾個方面:

  1. 伺服器的環境搭建,讓伺服器具有執行專案的必要環境

  2. 上傳你的專案程式碼到伺服器

  3. 配置伺服器代理,處理來自Internet上的請求。

1. 伺服器的環境搭建

首先說一下系統的選擇問題,先排除掉Windows系統,在Linux系統下,Ubuntu,Debian,CentOS都很不錯。

Ubuntu有強大的軟體源支援,但它更適合於桌面作業系統。Debian穩定,佔硬碟空間小,佔記憶體小,但發展過快,其安全性和穩定性都沒有CentOS好。所以我選擇了CentOS。對於三者的比較可以看 http://waynerqiu.com/7/156.html

買來的伺服器需要用遠端連線來操作,這裡推薦使用putty。我使用的是CentOS 6.3 x86_64,不同的版本可能在安裝軟體的地址可能會有些不同。

Linux系統下自帶了低版本的python,可以通過python -V檢視。自帶的python版本會和系統的一些功能有關聯,比如yum。

flask專案需要python2.7以上的版本,所以我們需要在系統中安裝python2.7或python3.5。

下載並安裝 Python 2.7.5:

#wget http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2 

如果此時沒有wget,可以通過yum install wget來安裝

#tar jxvf Python-2.7.5.tar.bz2
#cd Python-2.7.5
#./configure --prefix=/usr/local
#make && make install

這時的python2.7.5還不是我們系統將會使用的python(現在鍵入python -V後,顯示的還會是低版本的python)。所以需要建立軟連線,使系統預設的python指向python2.7.5。

#mv /usr/bin/python /usr/bin/python2.4.3   //你的python版本可能不同
#ln -s /usr/local/bin/python27 /usr/bin/python

使用了新版本的python會導致yum安裝軟體報錯,因為yum沒有相容python2.7,所以我們要指定yum使用的python版本。

#vi /usr/bin/yum

進入編輯模式,將#!/usr/bin/python改成#!/usr/bin/python2.7.5

安裝相關的開發工具盒和一些包

#yum groupinstall "Development tools"
#yum install zlib zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel

安裝pip

# wget https://pypi.python.org/packages/source/p/pip/pip-1.3.1.tar.gz --no-check-certificate

由於下載pip是基於https協議的,故需要在wget url後面加上--no-check-certificate,否則不能下載。

解壓和安裝pip

#chmod +x pip-1.3.1.tar.gz 
#tar xzvf pip-1.3.1.tar.gz 
#cd pip-1.3.1 
#python setup.py install 

在最後一步可能會報錯"ImportError: No module named setuptools",原因是沒有安裝setuptools

安裝setuptools

#wget https://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg  --no-check-certificate 
#chmod +x setuptools-0.6c11-py2.7.egg 
#sh setuptools-0.6c11-py2.7.egg 

這一步也有可能報錯"zlib not available",可以使用#rpm -qa | grep zlib 檢視可用的安裝包,將沒有安裝的安裝上(上面我們已經安裝了zlib和zlib-devel)

再次執行sh setuptools-0.6c11-py2.7.egg,發現還是報錯?同樣的錯誤?

那麼這應該不是zlib的問題,而是python的問題,我們需要重新編譯python2.7.5,在編譯之前需要修改一下Modules/Setup.dist檔案。找到

#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz

將註釋去掉,重新編譯python2.7.5

#cd Python-2.7.5
#./configure --prefix=/usr/local
#make && make install

這樣zlib應該可以用了,回到setuptools的安裝,再回到pip的安裝,這回總算把pip安裝上了。你可以在全域性環境下安裝flask相關的包(如果你的伺服器中包括將來只想執行一個專案的話),也可以將包安裝在虛擬環境中。先別急,把專案程式碼上傳了再說。

2. 上傳你的專案程式碼到伺服器

接下來可以上傳你的flask專案程式碼到伺服器上,可以使用flashFXP或者FileZilla來上傳。

這裡按照我的上傳目錄來介紹接下來的步驟,我的flask專案程式碼放在了 /home/www/WebBlogold(WebBlogold就是我的專案資料夾)。不明白Linux目錄結構?可以google一下,這裡推薦一篇 http://yangrong.blog.51cto.com/6945369/1288072

如果你的伺服器上有多個專案,那麼建議你安裝virtualenv虛擬環境。virtualenv可以解決專案與專案之間對同一個包的不同版本的依賴問題。

使用pip安裝virtualenv虛擬環境

pip install virtualenv 

進入專案目錄,在目錄下鍵入 virtualenv venv,其中venv是你要建的虛擬環境資料夾的名字,結果會出現下面兩行

New python executable in venv/bin/python
Installing setuptools, pip...done.

說明資料夾已經建好,使用 source venv/bin/activate 命令來啟用虛擬環境,啟用後你當前的路徑名的前面會有一個(venv)。

在虛擬環境下安裝flask相關包,你可以一個一個安裝,也可以將所有的包寫在一個txt檔案裡,一次性安裝。

flaskrelated.txt檔案:

Flask==0.10.1
Flask-Login==0.2.11
Flask-Mail==0.9.1
Flask-Moment==0.4.0
Flask-PageDown==0.1.5
Flask-SQLAlchemy==2.0
等等

儲存在你的專案資料夾下,在虛擬環境中鍵入 pip install -r flaskrelated.txt 來安裝他們。

3. 配置伺服器代理

我的伺服器代理是安裝在全域性中的,當然你也可以在虛擬環境裡安裝。

使用的代理一共有兩個,nginx和uwsgi,先說明一下,如果不用nginx一樣可以訪問你的專案,使用nginx的目的是為了安全和負載均衡。配置了nginx做前端代理,uwsgi作後端代理的伺服器(這裡所說的前後端都是相對的位置,並無實際含義),在處理來自Internet的請求時,要先經過nginx的處理,nginx把請求再交給uwsgi,經過uwsgi才能訪問到專案本身。

沒有nginx而只有uwsgi的伺服器,則是Internet請求直接由uwsgi處理,並反饋到我們的專案中。
nginx可以實現安全過濾,防DDOS等保護安全的操作,並且如果配置了多臺伺服器,nginx可以保證伺服器的負載相對均衡。

而uwsgi則是一個web伺服器,實現了WSGI協議(Web Server Gateway Interface),http協議等,它可以接收和處理請求,發出響應等。所以只用uwsgi也是可以的。

先安裝uwsgi

pip install uwsgi

在你的專案根目錄下建立一個配置檔案uwsgiconfig.ini(uwsgi支援多種配置檔案格式,xml,ini,json等)

[uwsgi]

socket = 127.0.0.1:8001     //啟動程式時所使用的地址和埠,通常在本地執行flask專案,
                            //地址和埠是127.0.0.1:5000,
                            //不過在伺服器上是通過uwsgi設定埠,通過uwsgi來啟動專案,
                            //也就是說啟動了uwsgi,也就啟動了專案。
chdir = /home/www/     //專案目錄

wsgi-file = manage.py      //flask程式的啟動檔案,通常在本地是通過執行  
                           //      python manage.py runserver 來啟動專案的

callable = app      //程式內啟用的application變數名

processes = 4     //處理器個數

threads = 2     //執行緒個數

stats = 127.0.0.1:9191      //獲取uwsgi統計資訊的服務地址

儲存配置檔案,我們可以通過鍵入 uwsgi uwsgiconfig.ini 來啟動uwsgi。

安裝nginx:由於nginx不在yum安裝軟體源裡,所以新增上

#rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
#yum install nginx

nginx的一些命令

  • 啟動: nginx

  • 停止: nginx -s -stop

  • 強制停止: pkill -9 nginx

  • 檢視nginx是否應用配置檔案: nginx -t

  • 檢視版本: nginx -v

先別急著啟動我們的nginx代理伺服器,先來寫一下nginx的配置檔案。

nginx的配置檔案在/etc/nginx/conf.d/資料夾下,也有可能在/etc/nginx/sites-enabled/default。我們開啟預設的配置檔案,大部分內容都是加註釋的,需要我們修改。

events {
    worker_connections  1024;
}
http {
    include       mime.types;    
    default_type  application/octet-stream;    
    sendfile        on;    
    keepalive_timeout  65;

    server {
        listen       80;         //預設的web訪問埠
        server_name  xxx.xxx.xxx.xxx;     //你的公網ip
        #charset koi8-r;
        access_log  /home/www/WebBlogold/logs/access.log;    //伺服器接收的請求日誌,
                                                             //需要在專案資料夾下建立
                                                             //logs資料夾,下同。
        error_log  /home/www/WebBlogold/logs/error.log;         //錯誤日誌

        location / {

            include        uwsgi_params;     //這裡是匯入的uwsgi配置

            uwsgi_pass     127.0.0.1:8001;   //需要和uwsgi的配置檔案裡socket項的地址
                                             //相同,否則無法讓uwsgi接收到請求。

            uwsgi_param UWSGI_PYHOME /home/www/WebBlogold/venv;   //python的位置(虛擬環境下)

            uwsgi_param UWSGI_CHDIR  /home/www/WebBlogold;     //專案根目錄

            uwsgi_param UWSGI_SCRIPT manage:app;     //啟動專案的主程式(在本地上執行
                                                     //這個主程式可以在flask內建的
                                                     //伺服器上訪問你的專案)

        }
    }
}
下面是一堆#,全都是註釋,不用管它。

在啟動nginx時,如果發現報錯"98:Address already in use",不要著急,很有可能是因為你的nginx已經啟動了。

通過 netstat -ntlp 檢視埠占用情況,看看是不是你的nginx佔用的80埠。如果發現有其他程式佔用了nginx的預設的80埠,可以殺掉這些程式,再啟動nginx。

到此,我們終於完成了所有的工作,馬上就可以訪問自己的專案了。

現在,檢查一下nginx的配置檔案是否應用 nginx -t 沒有成功應用的話,檢查一下配置檔案。

  1. 鍵入 nginx 來啟動nginx

  2. 鍵入uwsgi uwsgiconfig.ini 啟動uwsgi

這時uwsgi會告訴你你的專案是否有錯誤,如果本地執行良好,一般是沒有錯誤的。

有可能會報的錯是專案相關模組的引入路徑不對,修改一下便可。沒有報錯的話,開啟瀏覽器,輸入你的伺服器IP地址,或者如果你有相應的域名,並解析到了你的IP,輸入域名也可以。

如果一切順利的話,顯示的就是你想要的頁面了,如果不是,首先檢視一下日誌檔案,他們在你的專案根目錄下logs資料夾裡。

相關文章