很感謝隔壁及上海的後端同事幫助我很多(雖然他們應該不會看到這篇)
工作上寫了一點點後端(python),覺得最難的還是部署機器的部分,在 Linux 上設置 uWSGI 和 Nginx 主要是要讓寫好的後端 API 程式可以在虛擬機上跑起來並讓前端可以使用這些 API。
為什麼要用 uWSGI 和 Nginx
uWSGI 中的 WSGI 全名為 Web Server Gateway Interface,是一種協議,而 uWSGI 包含了 WSGI 協議,可以將 uWSGI 想像成是一座橋樑,一邊連接著與 Web Server(例如 Nginx),而另一邊則是接著後端 Flask 應用程式來做互相溝通。
Nginx 可以幫忙處理負載均衡以及反向代理,例如不同的網址都要指向我這台機器的 IP,而且是同個 port 的話就可以使用 Nginx,對於使用者來說會是從同個 port 連進來,但 Nginx 會將其分配到不同的 port 及服務上。(發現工作接觸的小專案似乎不用 Nginx 應該也不會有太大的影響,不過用了就還是筆記紀錄一下)
從 client(例如使用者透過瀏覽器發出 request)端到 Nginx 和 uWSGI 整個流程大概是這樣 :
安裝 uWSGI 和 Nginx
centOS 系列的 Linux 可以使用 yum 指令來安裝些軟體。
$ yum install nginx
安裝 python 相關的套件就需要使用 pip 指令。
$ pip install uwsgi
設置 uWSGI 和 Nginx
我將後端程式的檔案放在 /var/www/html 路徑下,並在此路徑下針對 uWSGI 新增一個 configure 檔案 project.ini。
$ vim /var/www/html/project.ini
用 vim 指令開啟該檔案,可以做編輯,如果該路徑下沒有該檔案會直接新增出一個檔案。(進入按下 i 會進入編輯模式、esc 後輸入 :q 會退出、esc 後輸入 :wq 會保存後退出,如果修改後不想保存後退出可點選 esc 後輸入 :q!)
檔案中輸入以下:
[uwsgi]module = app:app
# 要執行的檔案名稱及檔案中 flask 的名稱master = trueprocesses = 5http = 0.0.0.0:5002
# 啟動 http 監聽socket = /var/www/html/project.sock
# 與 nginx 溝通的檔案,我讓他跟此檔案放在一起,系統之後會自動生成這個檔案chdir = /var/www/html/project
# 後端程式檔案的路徑chmod-socket = 660vacuum = truedie-on-term = true
需要注意有使用到的 port 都要去設置防火牆,centOS 預設的防火牆為 firewalld,用以下指令開啟 5000 port 並重啟防火牆。
$ firewall-cmd --permanent --add-port=5000/tcp
$ firewall-cmd --reload
要讓虛擬機啟動 uWSGI,在 /etc/systemd/system 新增一個檔案為 project.service,檔案內容設置如下:
[Unit]
Description=uWSGI instance to app run
# 自行定義描述內容After=network.target[Service]
User=root
# 機器上的角色Group=nginx
WorkingDirectory=/var/www/html/project
# 主要執行的目錄路徑Environment="PATH=/root/project/projectenv/bin"
# 執行的環境ExecStart=/root/project/projectenv/bin/uwsgi --ini /var/www/html/project.ini
# 執行的檔案路徑RuntimeDirectory=app
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all[Install]
WantedBy=multi-user.target
接著來設定 nginx:
$ vim /etc/nginx/nginx.conf
新增以下的內容:
server {
listen 5000;
# API 使用的 port,也就是要監聽的 port location / {
include uwsgi_params;
uwsgi_pass unix:/var/www/html/project.sock;
# 用來跟 uWSGI 溝通的檔案
}
}
都設置完後,先啟用 nginx,輸入以下指令:(systemctl 為 system controller 的意思)
$ systemctl start nginx
接者啟用 uWSGI,輸入以下指令(systemctl 去啟動時都會去 /etc/systemd/system 路徑底下找符合的 configure 檔案)
$ systemctl start project
啟用後可以透過 status 來查看其狀態。(看是否啟用成功,裡面也會列出最新的幾筆日誌)
$ systemctl status project
後記
原本我將專案的後端檔案放在 nginx 沒權限的地方,導致一直無法成功,解決方式:
- 在 nginx.conf 中將第一行的 user 內容改為 root
- 或是將檔案放在 nginx 有權限的地方,像是 /var/www/html 底下
另外關於如果要查看詳細的日誌及報錯的內容,可透過以下指令,name 可換成要查詢的名稱,-n 會限制只列出 10 行。
$ journalctl -u <name> -n
或是下指令查看某天的日誌內容:
$ journalctl -u <name> --since "YYYY-MM-DD"