使用Nginx和Gunicorn在伺服器上部署Flask專案
Flask作為一個Web框架雖然自帶Web伺服器,但其Web伺服器主要用於開發階段的測試,在生產環境中應該選擇更專業的Web伺服器。當然在Web框架和Web伺服器之間還需要一個實現了WSGI協議的容器協助Web框架和Web伺服器之間通訊。
常用的WSGI協議容器有Gunicorn和uWSGI,當然也可以使用Tornado(還需要配合其它非同步框架)。
常用的Web伺服器有Nginx、Apache等,伺服器主要用來處理HTTP協議和一些靜態內容。
最終選擇了Gunicorn+Nginx的組合,因為Nginx的配置檔案書寫和Gunicorn的命令列啟動方式都相對要簡單一些。
下面是完整的步驟的部署步驟:
1. 在本機上利用PyCharm完成程式碼的開發。注意,開發環境最好是在python的虛擬環境中進行,因為後面要將專案部署到伺服器上,伺服器上也需要下載一遍專案中用到的各種庫。虛擬環境中的庫是保證專案正常執行的最少內容,因此到時候從伺服器上根據虛擬環境的requirments.txt下載對應的庫就可以了,不用下載額外的沒有必要的內容。
2. 程式碼開發完畢後,點選Pycharm下方的Terminal進入終端,從專案目錄繼續venv/Scripts目錄,呼叫activate進入虛擬環境,然後輸入:
pip freeze > 路徑/requirments.txt
會將開發時虛擬環境中的各種庫以及依賴庫的名稱版本都輸出到指定路徑處的requirments.txt檔案中。注意:requirments.txt名字可以任意起。
3. 利用
mysqldump -u使用者名稱 -p密碼 資料庫名稱 > 路徑/my.sql
該命令將開發時使用的資料庫內容全部匯出為sql檔案,到時候在伺服器上執行該sql檔案就可以將開發環境中的資料庫內容“複製”到伺服器的資料庫中。
4. 通過以上三步就完成了本地的所有工作,接下來進行伺服器端的配置。本人使用的阿里雲主機,選擇的映象為CentOS7.4 + Python 3.6.4 + MySQL 5.7,所以只要安裝一個Nginx伺服器和Gunicorn容器即可。
5. 正式安裝Nginx之前需要先保證CentOS上有必要的依賴內容,要安裝gcc gcc-c++等內容,使用CentOS的yum命令進行安裝:
yum -y install gcc gcc-c++ openssl-devel pcre-devel httpd-tools
6. 從Nginx官網選擇下載tar檔案(我下載的是1.15.3版本)並進行解壓,然後進入到解壓目錄中,進行安裝前的設定和模組檢測:
useradd nginx
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
首先在CentOS中增加一個nginx使用者,然後進行適當的設定(比如安裝路徑為/usr/local/nginx),然後進行必要的模組檢測,需要有需要可以新增更多,例如需要播放mp4的話可以新增--with-http_mp4_module等。
7. 通過檢測後,進行編譯和安裝
make && make install
安裝完畢後建立軟連線:
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
啟動nginx服務:
nginx
檢查nginx服務狀態:
netstat -ap | grep nginx
因為目前只是初次安裝,預設時nginx應該執行在80埠。在瀏覽器上輸入網址會看見nginx的歡迎畫面。
7. 將requirments.txt,sql檔案上傳到伺服器進行專案庫的下載和資料庫的建立。
專案庫的下載使用pip install命令安裝,可以選擇源為國內的源,比如豆瓣:
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com -r requirments.txt
進入mysql建立和開發環境一樣的資料庫,use資料庫後執行匯入sql檔案的命令:
source my.sql
根據my.sql中的指令,會在伺服器上創建出和開發環境一樣內容的資料庫。
8. 安裝Gunicorn容器:
pip install gunicorn
9. 在Nginx中配置Gunicorn:
修改Nginx安裝目錄下的配置檔案 /usr/local/nginx/conf/nginx.conf,將server段做簡單的修改:
server {
listen 80;
server_name xx.xx.xx.xx;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://0.0.0.0:9999;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
其中server_name的內容為主機的地址(可以是域名也可以是ip地址,我使用的是ip地址)
location中的相關內容就是為了將80埠的訪問轉發到9999埠。而9999埠將是Gunicorn執行Flask的埠。
改動配置檔案後,可以輸入如下指令檢測下配置檔案修改是否正確:
nginx -t
如果修改正確可以重啟一下Nginx服務(停止再啟動即可):
nginx -s stop #停止nginx服務
nginx #啟動nginx服務
netstat -ap | grep nginx #檢測nginx監聽埠
10. 利用Gunicorn裝載Flask啟動
將本地專案完整上傳到伺服器後,進入專案的根目錄,我的專案目錄結構為:
進入movie目錄後執行啟動Gunicorn的命令:
gunicorn -w 4 -b 0.0.0.0:9999 manager:app
埠為9999,後面是模組名稱:Flask例項名稱。
注意,在本地開發時,manager.py為啟動檔案,Flask在啟動檔案中的常規寫法有直接使用app.run配置埠的,或者利用flask_script的Manager,利用命令列runserver的,比如我的manager.py使用的就是Manager,在本地開發時利用runserver並設定埠號的方式啟動專案:
但是一旦使用了Gunicorn之後,一切主機地址和埠號設定全部由Gunicorn接管,只需要提供模組:Flask例項名稱即可。
11. 至此,伺服器端設定完畢。開啟瀏覽器輸入域名或主機地址,即可以看見專案首頁。