如何在 Ubuntu 18.04 上使用 Python 3 安裝 Flask

Flask 是一個非常簡單但非常靈活的框架,旨在為您的應用程序提供功能,而不會對結構和設計有太多限制。 您可以使用本文中描述的通用堆棧來為您設計的 Flask 應用程序提供服務。

在本文中,我們將在 Ubuntu 18.04 上使用 Flask 微框架設置一個簡單的 Python 應用程序。

本文的大部分內容將介紹如何設置 Gunicorn 應用服務器來啟動應用程序,以及如何設置 Nginx 作為前端反向代理。

先決條件

在開始閱讀本文之前,您應該在服務器上配置一個非 root 用戶。 該用戶需要有 sudo 權限,以便它可以執行管理功能。

創建非root用戶 sudo 權限配置:
1- 以根用戶身份登錄
2- 創建新用戶

# adduser bobby

3- 授予管理權限

要將這些權限添加到我們的新用戶,我們需要將新用戶添加到 sudo 團體。 默認情況下,在 Ubuntu 18.04 上,屬於 sudo 組被允許使用 sudo 命令。

# usermod -aG sudo bobby

從 Ubuntu 存儲庫安裝組件

第一步是從存儲庫安裝我們需要的所有部分。 我們將安裝 Python 3 包管理器 pip,以便安裝和管理我們的 Python 3 組件。 我們還將獲得構建一些 Gunicorn 組件所需的 Python 3 開發文件。 我們現在也將安裝 Nginx。
更新您的本地包索引,然後安裝這些包。 您需要的特定包將取決於您用於項目的 Python 版本。
安裝 Python 3,輸入:

$ sudo apt-get update
$ sudo apt-get install python3-pip python3-dev nginx

創建 Python 3 虛擬環境

接下來,我們將設置一個虛擬環境,以便將 Flask 應用程序與系統上的其他 Python 文件隔離開來。
首先使用 pip 安裝 virtualenv 包。
如果您使用的是 Python 3,請鍵入:

sudo pip3 install virtualenv

現在,我們可以為 Flask 項目創建一個父目錄。 創建後進入目錄:

mkdir ~/flaskproject
cd ~/flaskproject

我們可以通過鍵入以下內容來創建一個虛擬環境來存儲我們的 Flask 項目的 Python 需求:

virtualenv flaskprojectenv

這會將 Python 和 pip 的本地副本安裝到項目目錄中名為 flaskprojectenv 的目錄中。
在虛擬環境中安裝應用程序之前,我們需要激活它。 您可以通過鍵入:

source flaskprojectenv/bin/activate

您的提示將更改以指示您現在正在虛擬環境中操作。 它看起來像這樣 (flaskprojectenv)user@host:~/flaskproject$.

設置 Flask 應用程序

現在您處於虛擬環境中,我們可以安裝 Flask 和 Gunicorn 並開始設計我們的應用程序:

安裝 Flask 和 Gunicorn

我們可以使用本地實例 pip 安裝 Flask 和 Gunicorn。 鍵入以下命令以獲取這兩個組件:

筆記: 無論您使用的是哪個版本的 Python,當激活虛擬環境時,您都應該使用 pip 命令(不是 pip3)。

(flaskprojectenv) $ pip install gunicorn flask

創建示例應用程序

現在我們有可用的 Flask,我們可以創建一個簡單的應用程序。 Flask 是一個微框架。 它不包括功能更全的框架可能具有的許多工具,主要作為一個模塊存在,您可以將其導入到您的項目中以幫助您初始化 Web 應用程序。
雖然您的應用程序可能更複雜,但我們將在單個文件中創建我們的 Flask 應用程序,我們將其命名為 flaskproject.py:

(flaskprojectenv) $ nano ~/flaskproject/flaskproject.py

在這個文件中,我們將放置我們的應用程序代碼。 基本上,我們需要導入flask 並實例化一個Flask 對象。 我們可以使用它來定義在請求特定路由時應該運行的函數:

~/flaskproject/flaskproject.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def greeting():
    return "<h1 style="color:green">Hello World!</h1>"

if __name__ == "__main__":
    app.run(host="0.0.0.0")

這基本上定義了訪問根域時要呈現的內容。 Save 和 close 完成後的文件。

如果您遵循初始服務器設置指南,則應該啟用 UFW 防火牆。 為了測試我們的應用程序,我們需要允許訪問端口 5000。

通過鍵入以下內容打開端口 5000:

(flaskprojectenv) $ sudo ufw allow 5000

現在,您可以通過鍵入以下內容來測試您的 Flask 應用程序:

(flaskprojectenv) $ python flaskproject.py

訪問您服務器的域名或 IP 地址,然後是 :5000 在您的網絡瀏覽器中:

https://server_domain_or_IP:5000

您應該會看到如下內容:

完成後,點擊 CTRL-C 在終端窗口中幾次以停止 Flask 開發服務器。

創建 WSGI 入口點

接下來,我們將創建一個文件,作為我們應用程序的入口點。 這將告訴我們的 Gunicorn 服務器如何與應用程序交互。

我們將調用文件 wsgi.py

(flaskprojectenv) $ nano ~/flaskproject/wsgi.py

該文件非常簡單,我們可以簡單地從我們的應用程序中導入 Flask 實例,然後運行它:

~/flaskproject/wsgi.py
from flaskproject import app

if __name__ == "__main__":
    app.run()

Save 和 close 完成後的文件。

測試 Gunicorn 為項目服務的能力

在繼續之前,我們應該檢查 Gunicorn 是否可以正確執行。 我們可以通過簡單地將我們的入口點的名稱傳遞給它來做到這一點。 這是由模塊的名稱(減去 .py 擴展名,像往常一樣)加上應用程序中可調用的名稱。 在我們的例子中,這將是 wsgi:app.

我們還將指定要綁定的接口和端口,以便在公開可用的接口上啟動它:

(flaskprojectenv) $ cd ~/flaskproject
(flaskprojectenv) $ gunicorn --bind 0.0.0.0:5000 wsgi:app

再次訪問您的服務器的域名或 IP 地址,並在您的 Web 瀏覽器中再次將 :5000 附加到末尾:

https://server_domain_or_IP:5000

您應該會再次看到您的應用程序的輸出:

當您確認它運行正常後,按 CTRL-C 在您的終端窗口中。
我們現在已經完成了我們的虛擬環境,所以我們可以停用它:

(flaskprojectenv) $ deactivate

任何 Python 命令現在都將再次使用系統的 Python 環境。

創建一個 systemd 單元文件

我們需要處理的下一個部分是 systemd 服務單元文件。 創建一個 systemd 單元文件將允許 Ubuntu 的 init 系統在服務器啟動時自動啟動 Gunicorn 並為我們的 Flask 應用程序提供服務。

創建一個單元文件結尾 .service/etc/systemd/system 開始目錄:

$ sudo nano /etc/systemd/system/flaskproject.service

在裡面,我們將從 [Unit] 部分,用於指定元數據和依賴項。 我們將在此處描述我們的服務並告訴 init 系統僅在達到網絡目標後才啟動

接下來,我們將打開 [Service] 部分。 我們將指定我們希望進程在其下運行的用戶和組。 我們將授予我們的常規用戶帳戶所有權,因為它擁有所有相關文件。 我們將組所有權授予 www-data 組,以便 Nginx 可以輕鬆地與 Gunicorn 進程通信。

然後我們將映射出工作目錄並設置 PATH 環境變量,以便 init 系統知道進程的可執行文件位於何處(在我們的虛擬環境中)。 然後我們將指定啟動服務的命令。 Systemd 要求我們提供 Gunicorn 可執行文件的完整路徑,該文件安裝在我們的虛擬環境中。

我們將告訴它啟動 3 個工作進程(根據需要進行調整)。 我們還將告訴它在我們的項目目錄中創建並綁定到一個名為 flaskproject.sock. 我們將設置一個 umask 值 007 以便創建套接字文件以授予所有者和組的訪問權限,同時限制其他訪問權限。 最後,我們需要傳入 WSGI 入口點文件名和其中的 Python 可調用對象。

最後,我們將添加一個 [Install] 部分。 如果我們啟用它在啟動時啟動,這將告訴 systemd 將該服務鏈接到什麼。 我們希望此服務在常規多用戶系統啟動並運行時啟動:

/etc/systemd/system/flaskproject.service
[Unit]
Description=Gunicorn instance to serve flaskproject
After=network.target

[Service]
User=bobby
Group=www-data
WorkingDirectory=/home/bobby/flaskproject
Environment="PATH=/home/bobby/flaskproject/flaskprojectenv/bin"
ExecStart=/home/bobby/flaskproject/flaskprojectenv/bin/gunicorn --workers 3 --bind unix:flaskproject.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

至此,我們的 systemd 服務文件就完成了。 Save 和 close 現在。

我們現在可以啟動我們創建的 Gunicorn 服務並啟用它,以便它在啟動時啟動:

$ sudo systemctl start flaskproject
$ sudo systemctl enable flaskproject

配置 Nginx 來代理請求

我們的 Gunicorn 應用程序服務器現在應該啟動並運行,等待對項目目錄中套接字文件的請求。 我們需要通過對其配置文件進行一些小的添加來配置 Nginx 以將 Web 請求傳遞到該套接字。

首先在 Nginx 中創建一個新的服務器塊配置文件 sites-available 目錄。 我們將簡單地調用此flaskproject 以與本文的其餘部分保持一致:

$ sudo nano /etc/nginx/sites-available/flaskproject

打開一個 server 阻止並告訴 Nginx 偵聽默認端口 80。我們還需要告訴它使用此阻止來請求我們服務器的域名或 IP 地址。

我們需要添加的唯一另一件事是 location 匹配每個請求的塊。 在這個塊中,我們將包括 proxy_params 指定一些需要設置的通用代理參數的文件。 然後我們將請求傳遞給我們使用 proxy_pass 指示:

/etc/nginx/sites-available/flaskproject
server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include proxy_params;
        proxy_pass https://unix:/home/bobby/flaskproject/flaskproject.sock;
    }
}

這實際上就是我們為應用程序提供服務所需的全部內容。 Save 和 close 完成後的文件。

啟用 Nginx server 我們剛剛創建的塊配置,將文件鏈接到 sites-enabled 目錄:

$ sudo ln -s /etc/nginx/sites-available/flaskproject /etc/nginx/sites-enabled

使用該目錄中的文件,我們可以通過鍵入以下內容來測試語法錯誤:

$ sudo nginx -t

如果返回沒有任何問題,我們可以重新啟動 Nginx 進程以讀取我們的新配置:

$ sudo systemctl restart nginx

我們需要做的最後一件事是再次調整我們的防火牆。 我們不再需要通過端口 5000 進行訪問,因此我們可以刪除該規則。 然後我們可以允許訪問 Nginx 服務器:

$ sudo ufw delete allow 5000
$ sudo ufw allow 'Nginx Full'

您現在應該可以在 Web 瀏覽器中訪問服務器的域名或 IP 地址:

https://server_domain_or_IP

您應該會看到應用程序的輸出:

注意:配置 Nginx 後,下一步應該是使用 SSL/TLS 保護到服務器的流量。 這很重要,因為沒有它,包括密碼在內的所有信息都以純文本形式通過網絡發送。 獲取 SSL 證書以保護您的流量的最簡單方法是使用 Let’s Encrypt。

另請閱讀

  • 如何在 Ubuntu 18.04 上安裝 Let’s Encrypt SSL 證書
  • 如何在 Ubuntu 18.04 上設置 Django 開發環境
  • 如何在 Ubuntu 18.04 上安裝 LEMP

結論: 在本文中,我們在 Python 虛擬環境中創建了一個簡單的 Flask 應用程序。 我們創建了一個 WSGI 入口點,以便任何支持 WSGI 的應用程序服務器都可以與之交互,然後配置 Gunicorn 應用程序服務器來提供此功能。 之後,我們創建了一個 systemd 單元文件以在啟動時自動啟動應用程序服務器。 我們創建了一個 Nginx 服務器塊,將 Web 客戶端流量傳遞到應用程序服務器,中繼外部請求。