Flask 使用 Fabric 部署

2021-08-11 09:59 更新

Fabric 是一個(gè) Python 下類似于 Makefiles 的工具,但是能夠在遠(yuǎn)程服務(wù)器上 執(zhí)行命令。如果您有一個(gè)良好配置過(guò)的 Python 軟件包 (大型應(yīng)用) 且 對(duì)“配置”概念的理解良好,那么在外部服務(wù)器上部署 Flask 應(yīng)用將會(huì)非常容易。

開始之前,請(qǐng)先檢查如下列表中的事項(xiàng)是否都已經(jīng)滿足了:

  • 在本地已經(jīng)安裝了 Fabric 1.0 。即這個(gè)教程完成時(shí), Fabric 的最新版本。
  • 應(yīng)用程序已經(jīng)被封裝為包的形式,而且有一個(gè)有效的 setup.py 文件 (參考 部署和分發(fā))。
  • 在下文中的例子里,我們使用 mod_wsgi 作為遠(yuǎn)程服務(wù)器使用的服務(wù)端程序。 您當(dāng)然也可以使用您喜歡的服務(wù)端程序,但是考慮到 Apache 和 mod_wsgi 的 組合非常簡(jiǎn)單易用且容易安裝配置,并且在無(wú) root 權(quán)限的情況下,存在一個(gè)比較 簡(jiǎn)單的方法來(lái)重啟服務(wù)器。

創(chuàng)建第一個(gè) Fabfile

Fabfile 用于指定 Fabric 執(zhí)行的命令,它通常被命名為 fabfile.py 并使用 fab 命令運(yùn)行。文件中所有的函數(shù)將被當(dāng)做 fab 的子命令顯示出來(lái),他們可以在一個(gè)或 多個(gè)主機(jī)上運(yùn)行。這些主機(jī)要么在 fabfile 當(dāng)中定義,要么在命令輸入時(shí)指定。在本文中 我們將他們定義在 fabfile 里。

這是第一個(gè)基礎(chǔ)的例子,能夠?qū)F(xiàn)有源代碼上傳到指定服務(wù)器并將它們安裝進(jìn)如 一個(gè)已經(jīng)存在的虛擬環(huán)境中:

from fabric.api import *

# 遠(yuǎn)程服務(wù)器登陸使用的用戶名
env.user = 'appuser'
# 需要進(jìn)行操作的服務(wù)器地址
env.hosts = ['server1.example.com', 'server2.example.com']

def pack():
    # 以 tar 歸檔的方式創(chuàng)建一個(gè)新的代碼分發(fā)
    local('python setup.py sdist --formats=gztar', capture=False)

def deploy():
    # 之處發(fā)布產(chǎn)品的名稱和版本
    dist = local('python setup.py --fullname', capture=True).strip()
    # 將代碼歸檔上傳到服務(wù)器當(dāng)中的臨時(shí)文件夾內(nèi)
    put('dist/%s.tar.gz' % dist, '/tmp/yourapplication.tar.gz')
    # 創(chuàng)建一個(gè)文件夾,進(jìn)入這個(gè)文件夾,然后將我們的歸檔解壓到那里
    run('mkdir /tmp/yourapplication')
    with cd('/tmp/yourapplication'):
        run('tar xzf /tmp/yourapplication.tar.gz')
        # 使用我們虛擬環(huán)境下的 Python 解釋器安裝我們的包
        run('/var/www/yourapplication/env/bin/python setup.py install')
    # 現(xiàn)在我們的代碼已經(jīng)部署成功了,可以刪除這個(gè)文件夾了
    run('rm -rf /tmp/yourapplication /tmp/yourapplication.tar.gz')
    # 最終生成 .wsgi 文件,以便于 mod_wsgi 重新加載應(yīng)用程序
    run('touch /var/www/yourapplication.wsgi')

上面的代碼例子注釋很清晰,應(yīng)該很容易明白,下面是 fabric 常用命令的一個(gè)歸納:

  • run - 在遠(yuǎn)程服務(wù)器上執(zhí)行所有命令
  • local - 在本地執(zhí)行所有命令
  • put - 將指定文件上傳到指定服務(wù)器
  • cd - 改變遠(yuǎn)程服務(wù)器當(dāng)上的當(dāng)前操作目錄,此命令必須與 with 聲明一起使用

運(yùn)行 Fabfile

如何執(zhí)行 fabfile 呢?您應(yīng)該使用 fab 命令。若要發(fā)布當(dāng)前版本的代碼到遠(yuǎn)程 服務(wù)器上,您只需執(zhí)行如下命令:

$ fab pack deploy

然而這需要您的服務(wù)器已經(jīng)創(chuàng)建過(guò) /var/www/yourapplication 文件夾 而且 /var/www/yourapplication/env 是一個(gè)可用的虛擬環(huán)境。而且, 我們還沒(méi)有在服務(wù)器上創(chuàng)建配置文件或者 .wsgi 文件。因此,我們?cè)趺礃?把一個(gè)新的服務(wù)器轉(zhuǎn)換為可以使用基礎(chǔ)設(shè)備呢。

這視我們想要配置的服務(wù)器數(shù)量的不同,實(shí)現(xiàn)起來(lái)有所差別。如果我們只有一個(gè) 遠(yuǎn)程應(yīng)用服務(wù)器(大部分應(yīng)用都是都屬于此類),那么 fabfile 里添加一個(gè)專門 負(fù)責(zé)此類的命令有些小題大做。但是顯然我們可以這么做。在這里,您可以會(huì) 運(yùn)行命令 setup 或者 bootstrap 。然后將服務(wù)器的地址詳細(xì)地在命令行 當(dāng)中指定:

$ fab -H newserver.example.com bootstrap

初始化一個(gè)新的服務(wù)器,您大概需要執(zhí)行如下幾個(gè)步驟:

  1. 在 /var/www 目錄下創(chuàng)建目錄結(jié)構(gòu):

    $ mkdir /var/www/yourapplication
    $ cd /var/www/yourapplication
    $ virtualenv --distribute env
    
  2. 上傳一個(gè)新的 application.wsgi 文件以及為應(yīng)用程序準(zhǔn)備的配置 文件(例如: application.cfg)等到服務(wù)器上

  3. yourapplication 創(chuàng)建一個(gè)新的 Apache 配置,并激活它。請(qǐng)確保 激活了對(duì) .wsgi 改變的監(jiān)視功能,這樣在我們創(chuàng)建或改變這個(gè)文件時(shí) Apache 可以自動(dòng)重新加載應(yīng)用 (詳細(xì)內(nèi)容請(qǐng)參考 mod_wsgi (Apache))

現(xiàn)在的問(wèn)題是, application.wsgiapplication.cfg 文件 從何而來(lái)。

WSGI 文件

WSGI 文件應(yīng)導(dǎo)入這個(gè)應(yīng)用并且設(shè)定一個(gè)環(huán)境變量,這個(gè)環(huán)境變量指定了應(yīng)用程序應(yīng) 到哪里尋找配置文件。下面是一個(gè)完全完成上述功能的短例:

import os
os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg'
from yourapplication import app

應(yīng)用程序本身則應(yīng)該向下面這樣,通過(guò)查詢環(huán)境變量來(lái)查找配置,以此初始化自己:

app = Flask(__name__)
app.config.from_object('yourapplication.default_config')
app.config.from_envvar('YOURAPPLICATION_CONFIG')

這種方法在本文檔的 配置處理 這節(jié)中進(jìn)行了詳細(xì)介紹。

配置文件

正如上文所屬,應(yīng)用程序?qū)?huì)通過(guò)查找 YOURAPPLICATION_CONFIG 環(huán)境變量以 找到正確的配置文件。因此我們必須將配置文件放在應(yīng)用程序可以找到的地方。 配置文件有在不同電腦上表現(xiàn)出不同效果的特質(zhì),所以您不應(yīng)該以普通的方式 對(duì)它進(jìn)行版本控制。

一個(gè)流行的做法是將不同服務(wù)器的配置文件保存在不同的版本控制倉(cāng)庫(kù)里,然后 在不同的服務(wù)器中分別抽取出來(lái)。然后建立到從配置應(yīng)該在的地點(diǎn) (如: /var/www/yourapplication)到這個(gè)文件實(shí)際位置的符號(hào)鏈接。

我們預(yù)計(jì)只有一個(gè)或兩個(gè)服務(wù)器需要部署,因此我們采用另一種方法,也就是 提前手動(dòng)將配置文件上傳到需要的未知。

第一次部署

現(xiàn)在我們可以開始進(jìn)行第一次部署了。我們已經(jīng)初始化了服務(wù)器以使它擁有正確的 虛擬環(huán)境和已經(jīng)激活的 Apache 配置文件?,F(xiàn)在我們可以把應(yīng)用打包然后部署了:

$ fab pack deploy

Fabric 現(xiàn)在就會(huì)連接到所有服務(wù)器,然后運(yùn)行在 fabfile 文件中所指定的命令。 最初他會(huì)執(zhí)行打包工作,為我們創(chuàng)建代碼歸檔,然后他部署和上傳代碼到所有的 服務(wù)器,并在那里安裝他們。歸功于 setup.py ,所有引用依賴的包和庫(kù)都將 自動(dòng)被下載和安裝到我們的虛擬環(huán)境中。

下一步操作

從現(xiàn)在開始,我們可以做的事情變得如此之多,以至于部署代碼實(shí)際上可以 看做一種樂(lè)趣:

  • 創(chuàng)建一個(gè) bootstrap 命令用于初始化新的服務(wù)器,它將初始化一個(gè)新的虛擬環(huán)境 安裝以及適當(dāng)配置 Apache 等。
  • 將配置文件放置到一個(gè)獨(dú)立的版本控制倉(cāng)庫(kù)里,然后將活動(dòng)的配置符號(hào)連接到 它應(yīng)該在的地方。
  • 您應(yīng)該將您的應(yīng)用程序也放置到一個(gè)版本控制倉(cāng)庫(kù)中,然后在服務(wù)器中提取 最新的版本并安裝,您也可以很容易的回溯到以前的版本。
  • 為測(cè)試提供函數(shù)接口,這樣您就可以將測(cè)試代碼部署到服務(wù)器上并在服務(wù)器端 執(zhí)行測(cè)試套件。

使用 Fabric 是相當(dāng)有趣,鍵入 fab deploy 并看到您的應(yīng)用自動(dòng) 部署到一個(gè)或多個(gè)服務(wù)器上,您會(huì)有“簡(jiǎn)直像是魔術(shù)”這樣的感覺(jué)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)