Debian部署python3+flask+uwsgi+Nginx+Supervisor

沙河頂戰神發表於2017-11-12

一、安裝編譯用的包

  • 如果在root下就不用輸入 sudo。在子使用者下就在命令前加上 sudo。
  1. $ sudo apt-get install build-essential
  2. $ sudo apt-get install libncurses5-dev libncursesw5-dev libreadline6-dev
  3. $ sudo apt-get install libdb5.1-dev libgdbm-dev libsqlite3-dev libssl-dev
  4. $ sudo apt-get install libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev

二、下載安裝 python3

  1. 下載python3包

     $ wget --no-check-certificate https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz複製程式碼

    '下載可能會出現證照無效問題,只要安裝個ca-certificates或使用--no-check-certificate下載就可以避免下面的錯誤'

  2. 進入下載目錄
     $ cd 下載的目錄下/複製程式碼
  3. 解壓包
     $ tar -zxf Python-3.6.3.tgz複製程式碼
  4. 進入python3
     $ cd Python-3.6.3複製程式碼

三、編譯安裝

  1. 解決PIP包管理器所需依賴包
     $ vim Modules/Setup.dist複製程式碼
  2. 將下面1行取消註釋,大概在檔案的361行左右.修改後esc:wq儲存並退出
     zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz複製程式碼

四、自定義安裝目錄

  1. 建立安裝目錄
     $ mkdir -p /usr/local/python3.6.3複製程式碼
  2. 進入python3目錄
     $ cd Python-3.6.3複製程式碼
  3. 指定到安裝目錄
     $ ./configure --prefix=/usr/local/python3.6.3
     $ ./configure --enable-optimizations複製程式碼
  4. 這裡編譯使用的是make all沒有直接使用make,all引數會編譯所有子模組。

     $ make all
     $ make install複製程式碼

五、把 python3 新增到PATH裡

  1. 開啟~/.bashrc 檔案
  2. 新增執行路徑
     $ sudo vim ~/.bashrc
     export PATH=$PATH:/usr/local/python3.6.3/bin複製程式碼
    新增新的別名資訊來修改預設使用的Python版本
     alias python='/usr/bin/python3.6.3'複製程式碼
  3. 生效配置檔案
     $ source .bashrc複製程式碼
  4. 檢視版本:
    因為上面已經新增了預設使用python3.6.3,所以直接輸入$ python -V 會出現 (-bash: /usr/bin/python3.6.3: No such file or directory)報錯
     檢視python版本輸入以下:
     $ python2 -V :顯示為系統自帶的python2.7.3
     $ python3 -V :顯示為系統自帶的python3.6.3複製程式碼

六、安裝 Nginx

  1. 安裝
    $ sudo apt-get install nginx
    # 檢視版本
    $ nginx -v複製程式碼
  2. 啟動 nginx

     $ sudo /etc/init.d/nginx start複製程式碼

    瀏覽器訪問:你的伺服器ip地址 如:http://45.45.162.162


    出現上圖:表示成功

  3. 停止 nginx
     $ sudo nginx -s stop複製程式碼

七、安裝 uWSGI

  1. 因為已經安裝python3所以要使用pip3進行安裝
     $ pip3 install uwsgi複製程式碼
  2. 檢視版本
     $ uwsgi --version複製程式碼
  3. 安裝方法二:下載:
     $ wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gz複製程式碼
  4. 解壓:
     $ tar zxvf uwsgi-latest.tar.gz複製程式碼

八、測試

如果:有現成的專案可以把專案上傳到伺服器中,在git 管理專案,只需要 git clone 一下就可以了。

如果:你需要從本地上傳專案檔案,可以用scp命令,這裡就不囉嗦用法了。總之我們將專案檔案放到伺服器,然後就可以用virtualenv管理Python環境
virtualenv就不多說了。這裡直接用flask demo進行。

  1. 安裝虛擬環境

     $ pip3 install virtualenv複製程式碼
  2. 建立一個包

     $ mkdir myproject
     $ cd myproject複製程式碼
  3. 建立虛擬環境
     $ virtualenv env複製程式碼
    (1)啟用虛擬環境
     $ source env/bin/activate複製程式碼
    (2)在虛環境中安裝flask
     $ pip3 install flask複製程式碼
    (3)退出虛環境
     $ deactivate複製程式碼
    (4)建立啟動檔案
     $ vim run.py複製程式碼
    (5)寫入一個flask,埠自己進行設定。我這裡用的80埠。
     from flask import Flask
     app = Flask(__name__)
     @app.route("/")
     def hello():
         return "Hello World!"
     if __name__ == "__main__":
         app.run(host='0.0.0.0', port=80)複製程式碼
    (6)esc+wq儲存並且退出
  4. 執行這個run.py檔案
    (1)先停止Nginx
     $ nginx -s stop複製程式碼
    (2)開啟你設定的埠(埠預設全部是關閉狀態)埠自行設定。
     $ iptables -A INPUT -p tcp --dport 80 -j ACCEPT
     # 如果想關閉開啟的埠:
     $ iptables -A INPUT -p tcp --dport 80 -j DROP複製程式碼
    (3)啟動flask程式
     $ cd myproject
     $ python3 run.py複製程式碼
  5. 用其他電腦和手機4G訪問你的伺服器ip地址+上埠。
     如:http://45.32.122.555:80/
     出現:Hello World! 那就成功了。複製程式碼

九、配置 Nginx

  1. *
    (1)進入
     $ cd /etc/nginx/sites-enabled/複製程式碼
    (2)編輯default
     $ vim default複製程式碼
    —————————————————————————————————
     # 或者直接配置 $ cd /etc/nginx 
     $ vim nginx.conf
     # 不過要根據其語法來配置其實最後nginx.conf還是會呼叫/etc/nginx/sites-enabled/default的配置。複製程式碼
    (3)在最後寫入後 :wq儲存並且退出
     server {
     listen  80;
     server_name 45.32.162.255; 
     charset      utf-8;
     client_max_body_size 75M;
     location / {
         include      uwsgi_params;
         uwsgi_pass   127.0.0.1:8000;  
         uwsgi_param UWSGI_PYHOME /root/myproject/venv;
         uwsgi_param UWSGI_CHDIR  /root/myproject; 
         uwsgi_param UWSGI_SCRIPT run:app; 
         }
     }複製程式碼
    解析
    listen 80; # 伺服器監聽埠
    server_name 45.32.162.255; # 這裡寫你的域名或者公網IP
    charset utf-8; # 編碼
    client_max_body_size 75M; # 之前寫的關於GET和POST的區別
    include uwsgi_params; # 匯入uwsgi配置
    uwsgi_pass 127.0.0.1:8000; # 轉發埠,需要和uwsgi配置當中的監聽埠一致 (下面會配置uwsgi)
    uwsgi_param UWSGI_PYTHON /root/myproject/venv; # Python直譯器所在的路徑(這裡為虛擬環境)【路徑按照自己具體的路徑填寫】
    uwsgi_param UWSGI_CHDIR /root/myproject; # 專案根目錄
    uwsgi_param UWSGI_SCRIPT run:app; # 專案的主程式,即Flask app所在的位置【run是執行檔案run.py檔案(根據自己建立的檔名)app是falsk例項】

(4)測試一下配置檔案是否正確,若檢測配置檔案失敗,再好好檢查下配置檔案有沒有疏漏。

    $ nginx -t複製程式碼

# 表示測試成功

(5)此時訪問Nginx伺服器應該會得到502 Bad Gateway的提示,因為請求被Nginx轉發了,但是並沒有轉發伺服器來處理請求(還沒有配置好uwsgi)。

    $ service nginx start複製程式碼

十、配置 uwsgi

  1. # 在專案檔案根目錄新建配置檔案uwsgi.ini(uwsgi支援多種配置檔案格式: xml, ini, json等)
    (1)進入專案根目錄

     $ cd myproject複製程式碼

    (2)建立uwsgi檔案

     $ vim uwsgi.ini複製程式碼

    (3)寫入以下內容後 :wq儲存並退出

     [uwsgi]                                                     
     socket = 127.0.0.1:8000                         
     plugins = python                                        
     chidir = /root/myproject                                    
     wsgi-file = run.py                                       
     callable = app                  複製程式碼

    # uwsgi的監聽埠【要跟上面nginx配置裡的埠一樣】
    # 這行一定要加上,不然請求時會出現-- unavailable modifier requested: 0 --錯誤提示
    # 專案根目錄【路徑按照自己具體的路徑填寫】
    # flask程式的啟動檔案【這裡我命名為run.py】
    # 程式變數名 【app是falsk例項變數】

  2. 啟動測試
    (1)啟動 Nginx

     $ service nginx restart複製程式碼

    (2)啟動 uwsgi #注意要回到專案根目錄下執行

     $ cd ~
     $ cd myproject
     $ uwsgi uwsgi.ini
     若一切正常的話就可以在終端上看到uwsgi的啟動資訊了複製程式碼

    (3)開啟瀏覽器

     訪問你的ip加上埠
     例:http://45.32.162.255:80
     頁面出現:Hello World!複製程式碼

    # 說明Nginx和uwsgi配置成功了

    # 但離真正專案上線還差一段,因為uwsgi是直接在前臺啟動的,當我們的連線終端跟伺服器斷開的時候uwsgi程式也被關閉了,所以我們需要uwsgi在後臺執行。

    解釋一下上面這段話:我們在連線伺服器啟動專案後可以用瀏覽器訪問成功。但是我們一但關閉與伺服器的連線後再用瀏覽器訪問就不行了.專案是執行在前臺的也就是說.在關閉與伺服器連線的同時也關閉了伺服器的命令窗.執行在前臺的專案也同時關閉。所以我們需要把專案執行在後臺。

  3. 後臺啟動專案
    (1)用nohup啟動:不結束通話執行命令,用"&"可以讓你的命令在後臺執行
    (nohup詳細的命名引數請到官網查詢)注意:別漏了&號。
     $ nohup uwsgi uwsgi.ini &複製程式碼
    (2)關閉與伺服器的連線,然後用瀏覽器訪問你的ip地址:
     顯示:Hello World! 表示ok了!複製程式碼
    (3)可以通過命令把這個專案從後臺停止,查詢uwsgi的程式(linux命令不詳細說了)
     $ ps -ef|grep uwsgi複製程式碼
    找到uwsgi程式uwsgi.ini:
    root 7950 1 0 14:57 ? 00:00:00 uwsgi uwsgi.ini
    程式id每個人都不一樣 這裡的id是7950。
    (4)殺掉後臺的uwsgi程式kill -9 後面加上程式的id 或者 killall uwsgi殺掉全部同名為uwsgi的程式。
     $ kill -9 7950
     $ killall uwsgi複製程式碼
    (5)再用瀏覽器去訪問ip
     瀏覽器頁面顯示:502 Bad Gateway 表示停止掉uwsgi程式的執行複製程式碼
    (6)專案根目錄下會生成 nohup.out 記錄日誌

十一、使用Supervisor程式監控

# Supervisor是python2寫就的一款強大的運維工具。
目前Supervisor還不支援python3。可以通過以下方法解決。

可通過pip安裝.這裡用的是python3的pip.所以會安裝失敗.使用以下.

  1. 首先安裝supervisor (預設由自帶的python2.7驅動)
     $ apt-get install supervisor複製程式碼
  2. 進入預設配置檔案(修改配置檔案)

     $ cd /etc/supervisor/
     $ vim supervisord.conf 
     按shift+G 跳到末尾
     新增:files = /etc/supervisor/*.conf
     esc:wq 儲存複製程式碼

     這樣方便為每個app單獨設定conf檔案而不必全部寫在全域性設定裡面
     在啟動supervisorctl須先啟動supervisord。
     否則會出現error: 
     <class 'socket.error'>, [Errno 99] Cannot assign requested address: file: /usr/lib/python2.7/socket.py line: 575錯誤
    
     執行:(若不是在root下執行在最前面加上 sudo)
    
     $ supervisord -c /etc/supervisor/supervisord.conf
     $ supervisorctl -c /etc/supervisor/supervisord.conf
     # 這裡補充以一下:每當修改完配置後如果出現
     error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.
     # 請重新執行以上的兩句命令
    
     進入:supervisor shell模式表示成功
     退出:supervisor shell
     supervisor> exit複製程式碼
  3. 建立指令碼檔案,生成預設配置檔案.

     $ cd /etc/supervisor/conf.d/
     新建app.conf檔案(檔名自己定義)
     $ vim app.conf複製程式碼
  4. 進入編輯模式新增配置

     [program:myproject]
     directory = /root/myproject/
     command= uwsgi --ini /root/myproject/uwsgi.ini
     autostart = true
     startsecs = 5
     autorestart = true
     startretries = 3
     user = root
     redirect_stderr = true
     stdout_logfile_maxbytes = 20MB
     stdout_logfile_backups = 20
     stdout_logfile = /tmp/app.log
     stopasgroup=false
     killasgroup=false 複製程式碼

    esc:wq 儲存並退出

    # 解析
    [program:myproject]:# 專案的包名字(我的是myproject)

    directory = /root/myproject/:# 程式的啟動目錄路徑

    command= uwsgi --ini /root/myproject/uwsgi.ini:#啟動命令
    (相當於直接啟動 uwsgi uwsgi.ini一樣只是加上了路徑)

    autostart = true:# 在 supervisord 啟動的時候也自動啟動
    startsecs = 5: # 啟動 5 秒後沒有異常退出,就當作已經正常啟動了
    autorestart = true:# 程式異常退出後自動重啟
    startretries = 3:# 啟動失敗自動重試次數,預設是 3
    user = root: # 使用哪個使用者啟動(我這裡用的root)

    redirect_stderr = true:# 把 stderr 重定向到 stdout,預設 false
    stdout_logfile_maxbytes = 20MB:# stdout 日誌檔案大小,預設 50MB
    stdout_logfile_backups = 20:# stdout 日誌檔案備份數

    注意:stdout 日誌檔案,需要注意當指定目錄不存在時無法正常啟動,所以需要手動建立目錄(supervisord會自動建立日誌檔案)別忘了配置之後建立下面繼續。

    stdout_logfile = /tmp/app.log

    說下這兩個有用的配置項stopasgroup和killasgroup,如果我們用Flask等Rest服務,通常其會開啟幾個程式,那麼如果stopasgroup不啟用的話,supervisor無法重啟此服務(關閉主程式時其子程式沒有關閉,再開啟主程式時會提示埠被佔用等錯誤資訊)。

    stopasgroup=false:
    預設為 false,如果設定為 true,當程式收到 stop 訊號時,會自動將該訊號發給該程式的子程式。如果這個配置項為 true,那麼也隱含 killasgroup 為 true。例如在 Debug 模式使用 Flask 時,Flask 不會將接收到的 stop 訊號也傳遞給它的子程式,因此就需要設定這個配置項。

    killasgroup=false:
    預設為 false,如果設定為 true,當程式收到 kill 訊號時,會自動將該訊號發給該程式的子程式。如果這個程式使用了 python 的 multiprocessing 時,就能自動停止它的子執行緒。

         # 建立日誌的資料夾
         $ cd ~
         $ cd /myproject/
         $ mkdir tmp複製程式碼

    配置完成

    # 還有更多的配置引數請查閱官網

    #這裡我們可以看出,雖然supervisor是python2寫的,但只要我們指定執行的python3直譯器去執行程式就行了。

  5. 使配置生效(每當修改主配置檔案或增改子配置檔案都需要執行使它生效)
    需要先進入$ cd /etc/supervisor目錄或者專案的目錄cd myproject/才可以執行相關的命令如:supervisorctl reload等相關命令

     $ supervisorctl update # 因為是python3執行該命令可能會報錯
     # 可以使用以下命令:重新載入配置檔案
     $ supervisorctl reload複製程式碼
  6. 執行supervisorctl,即可進入shell裡面方便的操作,如start app、restart app等。

     $ cd /etc/supervisor
     $ supervisorctl
     $ start myproject # 你的專案名稱
     # 執行start後可以看到 myproject RUNNING pid 16758, uptime 0:02:58
     $ restart myproject # 重新啟動
     $ stop myproject # 停止
     # 更多相關命令可以到官網上查閱這裡不訊息介紹複製程式碼
  7. 以上我們只能在控制檯檢視執行.我們需要web介面上檢視

     # 新增修改配置檔案
     $ cd /etc/supervisor/
     $ vim supervisord.conf
     # 如果在vim模式下找到則對應修改
     # 如果沒有 按shift+G 跳至末尾新增
    
     # IP和繫結埠
     # 管理員名稱
     # 管理員密碼
     [inet_http_server]
     port = 45.32.111.111:9001   
     username = user 
     password = 666666
     # 如果不需要密碼可以註釋在最前面機上;號
     # ;username = user 
     # ;password = 666666
     # 重新載入配置檔案使它生效
     $ cd /etc/supervisor
     $ supervisorctl reload
     # 最後你需要開啟你的這個埠並且重啟supervisorctl
     $ iptables -A INPUT -p tcp --dport 9001 -j ACCEPT
     $ cd /etc/supervisor
     $ supervisorctl複製程式碼
  8. 用瀏覽器啟動

     # 輸入你的ip和埠
     45.32.111.111:9001複製程式碼

看到上圖介面表示已經成功,之後可以通過開啟Supervisor埠去監控管理你的專案一鍵啟動/停止你的專案。

——————————————————————————————————
有什麼遺漏不足的請多多指導!!!

覺得好的~點個贊打賞下咯~謝謝!!!

相關文章