騰訊雲Unubtu 16.04 (gunicorn+supervisor+ngnix+mongodb)部署Flask應用


1、申請騰訊雲服務

我申請了免費使用的雲服務器 ,選擇安裝的Linux版本是ubuntu16.04.1 LTSx86_64。我個人PC安裝使用的也是這個版本,比較熟悉些。

詳細參考幫助文檔

2、登錄雲主機

使用ssh公鑰方式登錄雲主機,ssh原理參考:SSH原理與運用(一):遠程登錄

在雲主機頁面點擊SSH密鑰,創建密鑰-->選擇已有的公鑰,輸入本機的ssh公鑰-->將此公鑰綁定到雲主機上。如下圖我創建本機的公鑰命名為thinkpads5。

本機的公鑰位於$HOME/.ssh/目錄下的id_rsa.pub文件內。如果沒有現成的,可以直接用ssh-keygen生成一個。


eliefly@thinkpad-s5:~/.ssh$ ls

id_rsa  id_rsa.pub  known_hosts

完成公鑰的綁定后(即將本機主機的公鑰傳送到雲主機上),雲主機的$HOME/.ssh/authorized_keys文件內就會保存本地主機的公鑰信息。

成功綁定后,可成功使用ssh公鑰登錄:


eliefly@thinkpad-s5:~$ ssh ubuntu@139.199.191.60

Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-53-generic x86_64)



 * Documentation:  https://help.ubuntu.com

 * Management:     https://landscape.canonical.com

 * Support:        https://ubuntu.com/advantage



Last login: Mon Jan  9 23:03:07 2017 from 58.251.190.158

ubuntu@VM-93-44-ubuntu:~$ ls /

bin   dev   initrd.img  lost+found  opt   run   srv  usr

boot  etc   lib         media       proc  sbin  sys  var

data  home  lib64       mnt         root  snap  tmp  vmlinuz

ubuntu@VM-93-44-ubuntu:~$ logout

Connection to 139.199.191.60 closed.

eliefly@thinkpad-s5:~$

3、部署一個簡單的WEB服務

自己的應用折騰半天沒成,就先從簡單的應用部署下,理清脈絡。

主要參考:python web 部署:nginx + gunicorn + supervisor + flask 部署筆記

在路徑/srv/helloworld下創建hello_tecent.py文件。


from flask import Flask

from flask_script import Manager

app = Flask(__name__)

manager = Manager(app)

@app.route("/")

def hello():

    return "hello tecent cloud!"

if __name__ == "__main__":

    manager.run()

同時$ pyvenv venv-helloworld創建虛擬環境venv-helloworld,激活虛擬環境,安裝必要的擴展包Flask Flask-Script


/srv/helloworld# ls

hello_tecent.py  venv-helloworld

驗證Flask程序能否正常啟動,如下項目啟動成功,virtualenv和flask項目部署ok。


(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# python hello_tecent.py runserver

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

4、使用 gunicorn 部署 flask web

上面我們使用 flask 自帶的服務器,完成了 web 服務的啟動。生產環境下,flask 自帶的 服務器,無法滿足性能要求。我們這里采用 gunicorn 做 wsgi容器,用來部署 python。

webservice 的方式同樣也有很多方式。常見的有FastCGI,WSGI等。我們采用gunicorn為 wsgi容器。

安裝gunicorn,注意此處的gunicorn同樣是需要安裝在虛擬環境下。在激活虛擬環境的情況下,使用sudo pip install gunicorn安裝,會把gunicorn雲主機實體環境中。為安裝正確,先獲取root權限再安裝。

獲取雲主機root權限:$ sudo /bin/su - root



ubuntu@VM-93-44-ubuntu:/srv/helloworld$ sudo /bin/su - root

root@VM-93-44-ubuntu:~# cd /srv/helloworld/

root@VM-93-44-ubuntu:/srv/helloworld# source ./venv-helloworld/bin/activate

(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# pip install gunicorn

之前使用 Flask-Script擴展來啟動Flask服務器,執行# python hello_tecent.py runserver,服務器由manager.run()

gunicorn安裝好 之后,需要用gunicorn啟動 flask。執行$ ./venv-helloworld/bin/gunicorn hello_tecent:app -w 4 -b 0.0.0.0:8000啟動服務器。

此處,hello_tecent.py 就等同於一個庫文件,被 gunicorn 調用。app為Flask 程序實例名,源碼中app = Flask(__name__)。使用 8000 的端口進行訪問,原先的5000並沒有啟用。-w 表示開啟多少個 worker,-b 表示 gunicorn 開發的訪問地址。


(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# ./venv-helloworld/bin/gunicorn hello_tecent:app -w 4 -b 0.0.0.0:8000

[2017-01-15 22:47:55 +0800] [21387] [INFO] Starting gunicorn 19.6.0

[2017-01-15 22:47:55 +0800] [21387] [INFO] Listening at: http://0.0.0.0:8000 (21387)

[2017-01-15 22:47:55 +0800] [21387] [INFO] Using worker: sync

[2017-01-15 22:47:55 +0800] [21390] [INFO] Booting worker with pid: 21390

[2017-01-15 22:47:55 +0800] [21391] [INFO] Booting worker with pid: 21391

[2017-01-15 22:47:55 +0800] [21393] [INFO] Booting worker with pid: 21393

[2017-01-15 22:47:55 +0800] [21394] [INFO] Booting worker with pid: 21394

WEB服務啟動成功后,就可以在本機瀏覽器訪問雲主機的WEB服務。瀏覽器地址欄輸入:<ip address>:8000,就可以看到親切的 hello tecent cloud!

5.安裝 supervisor

想要結束 gunicorn 只需執行 pkill gunicorn,有時候還的 ps 找到 pid 進程號才能 kill。可是這對於一個開發來說,太過於繁瑣,因此出現了另外一個神器---supervisor,一個專門用來管理進程的工具,還可以管理系統的工具進程。

supervisor python3中不支持,我虛擬環境下使用的是python3.5,無法安裝 supervisor。


(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# pip install supervisor

Collecting supervisor

  Downloading supervisor-3.3.1.tar.gz (415kB)

    100% |################################| 419kB 716kB/s 

    Complete output from command python setup.py egg_info:

    Supervisor requires Python 2.4 or later but does not work on any version of Python 3.  You are using version 3.5.2 (default, Nov 17 2016, 17:05:23)

    [GCC 5.4.0 20160609].  Please install using a supported version.

    

    ----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-0bi4mj2b/supervisor/

supervisor安裝在雲主機實體環境python2下(ubuntu16.04自帶python2和python3)。


# pip install supervisor

將其原始配置文件重定向到程序根目錄(需要root權限,sudo執行也失敗):


# echo_supervisord_conf>supervisor.conf

我的工程目錄是/srv/helloworld,新建log目錄,在/srv/helloworld/supervisor.conf配置文件底部添加,hello_tecent。


[program:hello_tecent]

command=/srv/helloworld/venv-helloworld/bin/gunicorn -w4 -b 0.0.0.0:8000 hello_tecent:app    ; supervisor啟動命令

directory=/srv/helloworld                                                 ; 項目的文件夾路徑

startsecs=0                                                                             ; 啟動時間

stopwaitsecs=0                                                                          ; 終止等待時間

autostart=false                                                                         ; 是否自動啟動

autorestart=false                                                                       ; 是否自動重啟

stdout_logfile=/srv/helloworld/log/gunicorn.log                           ; log 日志

stderr_logfile=/srv/helloworld/log/gunicorn.err   

supervisor的基本使用命令:


supervisord -c supervisor.conf                             通過配置文件啟動supervisor

supervisorctl -c supervisor.conf status                    察看supervisor的狀態

supervisorctl -c supervisor.conf reload                    重新載入 配置文件

supervisorctl -c supervisor.conf start [all]|[appname]     啟動指定/所有 supervisor管理的程序進程

supervisorctl -c supervisor.conf stop [all]|[appname]      關閉指定/所有 supervisor管理的程序進程

運行成功:


root@VM-93-44-ubuntu:/srv/helloworld# supervisord -c ./supervisor.conf

root@VM-93-44-ubuntu:/srv/helloworld# supervisorctl -c ./supervisor.conf start hello_tecent

hello_tecent: started

root@VM-93-44-ubuntu:/srv/helloworld#  supervisorctl -c ./supervisor.conf status           

hello_tecent                     RUNNING   pid 2411, uptime 0:01:08

root@VM-93-44-ubuntu:/srv/helloworld# ps -ef | grep supervisor

root      2409     1  0 00:15 ?        00:00:00 /usr/bin/python /usr/bin/supervisord -c ./supervisor.conf

root      2549  1843  0 00:17 pts/0    00:00:00 grep --color=auto supervisor

此時本機瀏覽器打開外網<ip address>:8000便可看到hello tecent cloud!。

可能出現的錯誤:

1) Another program is already listening on a port that one of our HTTP servers is configured to use.


$ supervisord -c supervisor.conf

Error: Another program is already listening on a port that one of our HTTP servers is configured to use.  Shut this program down first before starting supervisord.

For help, use /usr/bin/supervisord -h

解決:執行ps -ef | grep supervisor找到supervisord進程kill掉。

2)Unlinking stale socket /tmp/supervisor.sock

解決:sudo unlink /tmp/supervisor.sock

上面直接把hello_tecent程序的supervisor配置追加到supervisor.conf文件的末尾。其實,hello_tecent程序的supervisor配置文件也可放置在其他目錄下,如在目錄/srv/helloworld/conf.d/下新建文件 hello_tecnet.ini,相應的supervisor.conf文件的末尾修改為如下,包含關系。這樣有多個監控程序時方便管理。


[include]

files = ./conf.d/hello_tecent.ini

6、安裝使用nginx代理

nginx 不用多說,一個高性能的web服務器。通常用來在前端做反向代理服務器。所謂正向與反向(reverse),只是英文說法翻譯。代理服務,簡而言之,一個請求經過代理服務器從局域網發出,然后到達互聯網上服務器,這個過程的代理為正向代理。如果一個請求,從互聯網過來,先進入代理服務器,再由代理服務器轉發給局域網的目標服務器,這個時候,代理服務器為反向代理(相對正向而言)。

簡言之,正向代理:客戶端和代理服務器在一起,反向代理器:服務器和代理在一起。


正向代理:{ 客戶端 --->代理服務器 } ---> 服務器

反向代理:客戶端 --->{ 代理服務器 ---> 服務器 }

{} 表示局域網

ngnix的配置放在/etc/nginx/sites-available 139.199.191.60是所申請的雲主機公網IP,sudo vim hello-tecent




然后在/etc/nginx/sites-enabled/目錄下創建軟鏈接:


$ sudo ln -s /etc/nginx/sites-available/hello-tecent /etc/nginx/sites-enabled/

讓Nginx重新加載配置文件並重啟nginx服務:


ubuntu@VM-93-44-ubuntu:/$ sudo /etc/init.d/nginx restart

[ ok ] Restarting nginx (via systemctl): nginx.service.

ubuntu@VM-93-44-ubuntu:/$ sudo /etc/init.d/nginx reload

[ ok ] Reloading nginx configuration (via systemctl): nginx.service.

在本機瀏覽器輸入http://139.199.191.60/,注意此時由於ngixn反向代理作用,可以省去端口號進行訪問到hello tecent cloud!了。


$ sudo supervisorctl -c supervisor.conf status

hello_tecent                     RUNNING   pid 1036, uptime 0:00:44

7、下面部署自己的Flask應用

有Flaks+Mongodb構建的博客網站,Git源碼位置:NovBlog

7.1 部署代碼至雲主機

我們使用Fabric部署代碼至雲主機/srv/NovBlog目錄,也可使用Git Clone或者FTP傳遞等方式。

Fabric參考:Day 15 - 部署Web App

7.2 安裝Mongodb數據庫。

Ubuntu 16.04安裝Mongodb參考How to Install and Configure MongoDB on Ubuntu 16.04

7.3 按照之前的方式安裝配置gunicorn,supervisor 和 ngnix。

supervisor配置文件:


[program:novblog]

command=/srv/NovBlog/venv-novblog/bin/gunicorn -w4 -b 0.0.0.0:8000 manage:app    ; supervisor啟動命令

directory=/srv/NovBlog/www                                                 ; 項目的文件夾路徑,manage.py所在

startsecs=0                                                                             ; 啟動時間

stopwaitsecs=0                                                                          ; 終止等待時間

autostart=false                                                                         ; 是否自動啟動

autorestart=false                                                                       ; 是否自動重啟

stdout_logfile=/srv/NovBlog/log/gunicorn.log                           ; log 日志

stderr_logfile=/srv/NovBlog/log/gunicorn.err   

nginx配置:

配置屏蔽部分,如果不屏蔽會有問題,會導致static路徑出錯,源碼中引用靜態資源是使用如<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">,需要再研究下配置中static如何與href中匹配。


server {

    listen      80;

    server_name 139.199.191.60; # 這是HOST機器的外部域名,用地址也行



    root       /srv/NovBlog/www/;

    access_log /srv/NovBlog/log/access_log;

    error_log  /srv/NovBlog/log/error_log;



    # location /favicon.ico {

    #    root /srv/NovBlog/www/app/static/img;

    # }



    # location ~ ^\/static\/.*$ {

    #    root /srv/NovBlog/www/app/static;

    # }



    location / {

        proxy_pass       http://127.0.0.1:8000;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }

}

7.4 綁定域名

域名沒買,參考操作:

域名解析添加A型記錄,值為雲服務器外網ip即可。
nginx配置相應的一行代碼亦需改一下:


$ server_name <域名>;

此時,在網址欄輸入域名即可進入網站。


參考:

1、在騰訊雲上部署flask應用

2、python web 部署:nginx + gunicorn + supervisor + flask 部署筆記


免責聲明!

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



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