在 Azure 中透過 PostgreSQL 部署 Python (Django 或 Flask) Web 應用程式

在本教學課程中,您會將資料驅動的 Python Web 應用程式 (DjangoFlask) 部署至 Azure App ServiceAzure Database for PostgreSQL 關聯式資料庫服務。 Azure App Service 在 Linux 伺服器環境中支援 Python

An architecture diagram showing an App Service with a PostgreSQL database in Azure.

若要完成本教學課程,您需要:

跳到結尾

安裝 Azure Developer CLI 後,您可以部署本教學課程中顯示的完整設定範例應用程式,並看到這在 Azure 中執行。 只要在空的工作目錄中執行下列命令:

azd auth login
azd init --template msdocs-flask-postgresql-sample-app
azd up

範例應用程式

提供使用 Flask 和 Django 架構的 Python 應用程式範例,以協助您遵循本教學課程。 若要部署應用程式但不在本機執行,請略過此部分。

若要在本機執行應用程式,請確定您已在本機安裝 Python 3.7 或更新版本PostgreSQL。 接著,複製範例存放庫的 starter-no-infra 分支,並切換至存放庫根路徑。

git clone -b starter-no-infra https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app
cd msdocs-flask-postgresql-sample-app

使用 .env.sample 檔案做為指南建立如下所示的 .env 檔案。 將 DBNAME 的值設定為本地 PostgreSQL 執行個體中現有資料庫的名稱。 針對本地 PostgreSQL 執行個體適當地設定 DBHOSTDBUSERDBPASS 的值。

DBNAME=<database name>
DBHOST=<database-hostname>
DBUSER=<db-user-name>
DBPASS=<db-password>

建立應用程式的虛擬環境:

py -m venv .venv
.venv\scripts\activate

安裝相依性:

pip install -r requirements.txt

使用下列命令執行應用程式範例:

# Run database migration
flask db upgrade
# Run the app at http://127.0.0.1:5000
flask run

1.建立 App Service 和 PostgreSQL

git clone https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app.git

在此步驟中,您會建立 Azure 資源。 本教學課程中使用的步驟會建立一組預設保護資源,其中包含 App Service 和 Azure Database for PostgreSQL。 針對建立程序,您將指定:

  • Web 應用程式的 [名稱]。 此名稱會以 https://<app-name>.azurewebsites.net 的形式作為 Web 應用程式 DNS 名稱的一部分。
  • 要實際執行應用程式的區域
  • 應用程式的執行階段堆疊。 您可以在此處選取要用於應用程式的 Python 版本。
  • 應用程式的主控方案。 這是定價層,其中包含應用程式的一組功能和調整限度。
  • 應用程式的 [資源群組]。 資源群組允許您將應用程式所需的所有 Azure 資源分組 (在邏輯容器中)。

登入 Azure 入口網站,遵循下列步驟建立您的 Azure App Service 資源。

第 1 步:在 Azure 入口網站中:

  1. 在 Azure 入口網站頂端的搜尋列中輸入「Web 應用程式資料庫」。
  2. 選取 [Marketplace] 標題下標示為 [Web 應用程式 + 資料庫] 的項目。 您也可以直接瀏覽至建立精靈

A screenshot showing how to use the search box in the top tool bar to find the Web App + Database creation wizard (Flask).

第 2 步:在 [建立 Web 應用程式 + 資料庫] 頁面上,填寫表單,如下所示。

  1. 資源群組 →選取 [新建],並使用名稱 msdocs-python-postgres-tutorial
  2. 區域 → 您附近的任何 Azure 區域。
  3. 名稱msdocs-python-postgres-XYZ,其中 XYZ 是任意三個隨機字元。 此名稱在整個 Azure 中必須是唯一的。
  4. 執行階段堆疊Python 3.10
  5. 資料庫PostgreSQL - 彈性伺服器會依預設選取做為資料庫引擎。 伺服器名稱和資料庫名稱預設也會設定為適當的值。
  6. 主控方案基本。 當一切就緒時,您可以在之後擴大至生產定價層。
  7. 選取 [檢閱 + 建立]。
  8. 驗證完成時,選取 [建立]

A screenshot showing how to configure a new app and database in the Web App + Database wizard (Flask).

第3 步:部署需要數分鐘的時間才能完成。 在部署完成時,選取 [前往資源] 按鈕。 系統會將您直接帶至 App Service 應用程式,但會建立下列資源:

  • 資源群組 → 所有已建立資源的容器。
  • App Service 計畫 → 定義 App Service 的計算資源。 系統會建立基本層中的 Linux 方案。
  • App Service → 代表您的應用程式,並在 App Service 方案中執行。
  • 虛擬網路 → 與 App Service 應用程式整合,並隔離後端網路流量。
  • Azure Database for PostgreSQL 彈性伺服器 → 只能從虛擬網路內部存取。 系統會為您在伺服器上建立資料庫和使用者。
  • 私人 DNS 區域 → 啟用虛擬網路中 PostgreSQL 伺服器的 DNS 解析。

A screenshot showing the deployment process completed (Flask).

2.驗證連線設定

建立精靈已為您產生連線變數做為應用程式設定。 應用程式設定是將連線秘密保留在程式碼存放庫外部的一個方法。 當您準備好將祕密移至更安全的位置時,以下是在 Azure Key Vault 中儲存的文章。

第 1 步:在 App Service 頁面上的左側功能表,選取 [組態]

A screenshot showing how to open the configuration page in App Service (Flask).

第 2 步:在 [設定] 頁面的 [應用程式設定] 索引標籤中,確認 AZURE_POSTGRESQL_CONNECTIONSTRING 存在。 這些設定將會以環境變數的形式插入執行階段環境。

A screenshot showing how to see the autogenerated connection string (Flask).

第 3 步: 在終端機或命令提示字元中,執行下列 Python 指令碼來產生唯一的祕密:python -c 'import secrets; print(secrets.token_hex())'。 請複製輸出值,以用於下一個步驟。

3.部署範例程式碼

在此步驟中,您將使用 GitHub Actions 來設定 GitHub 部署。 這只是部署至 App Service 的許多方式之一,但也是在部署程序中持續整合的絕佳方式。 根據預設,您 GitHub 存放庫的每個 git push 都會開始建置和部署動作。

第 1 步:在新的瀏覽器視窗中:

  1. 登入您的 GitHub 帳戶。
  2. 瀏覽至 https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app
  3. 請選取分叉
  4. 選取 [建立派生]

A screenshot showing how to create a fork of the sample GitHub repository (Flask).

第 2 步:在 GitHub 頁面中,按下 . 鍵,在瀏覽器中開啟 Visual Studio Code。

A screenshot showing how to open the Visual Studio Code browser experience in GitHub (Flask).

第 3 步:在瀏覽器中的 Visual Studio Code,在總管中開啟 azureproject/production.py。 查看生產環境中所使用的環境變數,包括您在設定頁面中看到的應用程式設定。

A screenshot showing Visual Studio Code in the browser and an opened file (Flask).

第 4 步:回到 [App Service] 頁面的左側功能表中,選取 [部署中心]

A screenshot showing how to open the deployment center in App Service (Flask).

第 5 步:在 [部署中心] 頁面上:

  1. 在 [來源] 中,選取 [GitHub]。 根據預設,系統會選取 GitHub Actions 作為組建提供者。
  2. 登入您的 GitHub 帳戶,並遵循提示來授權 Azure。
  3. 在 [組織] 中,選取您的帳戶。
  4. 在 [存放庫] 中,選取 msdocs-flask-postgresql-sample-app
  5. 在 [分支] 中,選取 [main]
  6. 將選擇預設選項保留為 [新增工作流程]
  7. 在 [驗證類型]下,選取 [使用者指派的身分識別]
  8. 在最上層的功能表中,選取 [儲存]。 App Service 會將工作流程檔案認可至 .github/workflows 目錄中選擇的 GitHub 存放庫。

A screenshot showing how to configure CI/CD using GitHub Actions (Flask).

第 6 步:在 [部署中心] 頁面上:

  1. 選取 [記錄] 。 已啟動部署執行。
  2. 在部署執行的記錄項目中,選取 [建置/部署記錄]

A screenshot showing how to open deployment logs in the deployment center (Flask).

第 7 步:您已前往 GitHub 存放庫,並看到 GitHub 動作正在執行。 工作流程檔案會定義兩個不同的階段:建置和部署。 等候 GitHub 執行到顯示 [完成] 狀態。 需要約 5 分鐘的時間。

A screenshot showing a GitHub run in progress (Flask).

有問題嗎? 請查看疑難排解指南

4.產生資料庫結構描述

透過受虛擬網路保護的 PostgreSQL 資料庫,執行 Flask 資料庫移轉最簡單的方式是在 SSH 工作階段搭配 App Service 容器中。

第 1 步:在 App Service 頁面上的左側功能表,

  1. 選取 [SSH]
  2. 選取 [執行]

A screenshot showing how to open the SSH shell for your app from the Azure portal (Flask).

第 2 步:在 SSH 終端機中,執行 flask db upgrade。 如果成功,App Service 已成功連線至資料庫。 只有 /home 中檔案的變更才能在應用程式重新開機之後保存。 /home 以外的變更不會保存。

A screenshot showing the commands to run in the SSH shell and their output (Flask).

5.瀏覽至應用程式

第 1 步:在 [App Service] 頁面中:

  1. 從左側功能表中選取 [概觀]
  2. 選取應用程式的 URL。 您也可以直接瀏覽至 https://<app-name>.azurewebsites.net

A screenshot showing how to launch an App Service from the Azure portal (Flask).

第 2 步: 將幾個餐廳新增至清單中。 恭喜,您正在 Azure App Service 中執行 Web 應用程式,並安全地連線至 PostgreSQL 的適用於 PostgreSQL 的 Azure 資料庫。

A screenshot of the Flask web app with PostgreSQL running in Azure showing restaurants and restaurant reviews (Flask).

6.資料流診斷記錄

Azure App Service 會擷取輸出到主控台的所有訊息,以協助您診斷應用程式的問題。 如下所示,樣本應用程式包含可示範這項功能的 print() 陳述式。

@app.route('/', methods=['GET'])
def index():
    print('Request for index page received')
    restaurants = Restaurant.query.all()
    return render_template('index.html', restaurants=restaurants)

第 1 步:在 [App Service] 頁面中:

  1. 從左側功能表中,選取 [App Service 記錄]
  2. 在 [應用程式記錄] 下,選取 [檔案系統]
  3. 在最上層的功能表中,選取 [儲存]

A screenshot showing how to enable native logs in App Service in the Azure portal.

第 2 步:從左側功能表中,選取 [記錄串流]。 您會看到應用程式的記錄,包括平台記錄和來自容器內的記錄。

A screenshot showing how to view the log stream in the Azure portal.

深入了解如何在設定適用於 Python 應用程式的 Azure 監視器系列中記錄 Python 應用程式。

7.清除資源

完成後,您可以刪除資源群組,以從 Azure 訂用帳戶中刪除所有資源。

第 1 步:在 [Azure 入口網站] 頂端的搜尋列中:

  1. 輸入資源群組名稱。
  2. 選取資源群組。

A screenshot showing how to search for and navigate to a resource group in the Azure portal.

第 2 步:在 [資源群組] 頁面中,選取 [刪除資源群組]

A screenshot showing the location of the Delete Resource Group button in the Azure portal.

步驟 3:

  1. 輸入您確認要刪除的資源群組名稱。
  2. 選取 [刪除]

A screenshot of the confirmation dialog for deleting a resource group in the Azure portal.

1.建立 Azure 資源並部署範例應用程式

在此步驟中,您會建立 Azure 資源,並將範例應用程式部署至 Linux 上的 App Service。 本教學課程中使用的步驟會建立一組預設保護資源,其中包含 App Service 和 Azure Database for PostgreSQL。

  1. 如果您尚未這麼做,請在本機終端機中複製範例存放庫的 starter-no-infra 分支。

    git clone -b starter-no-infra https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app
    cd msdocs-flask-postgresql-sample-app
    

    此複製的分支是您起點。 它包含簡單的資料磁碟驅動器 Flask 應用程式。

  2. 從存放庫根路徑中執行 azd init

    azd init --template python-app-service-postgresql-infra
    
  3. 出現提示時,請提供下列答案:

    問題 回答
    目前的目錄不是空的。 您是否要在「<您的目錄>」初始化專案? Y
    您要對這些檔案執行什麼動作? 維持現有的檔案不變
    輸入新的環境名稱 輸入唯一名稱。 azd 範本會使用此名稱作為 Azure 中 Web 應用程式的 DNS 名稱的一部分 (<app-name>.azurewebsites.net)。 允許英數字元與連字號。
  4. 執行 azd up 命令來佈建必要的 Azure 資源,並部署應用程式程式代碼。 如果您尚未登入 Azure,瀏覽器將啟動並要求您登入。 azd up 命令也會提示您選取要部署的訂用帳戶和位置。

    azd up
    

    azd up 命令可能需要幾分鐘才能完成。 這也會編譯及部署您的應用程式程序代碼,但稍後會修改程序代碼以使用 App Service。 執行時,命令會提供佈建和部署程式的相關資訊,包括 Azure 中部署的連結。 完成時,命令也會顯示部署應用程式的連結。

    此 azd 範本包含檔案 (azure.yamlinfra directory),其預設會使用下列 Azure 資源產生安全架構:

    • 資源群組 → 所有已建立資源的容器。
    • App Service 計畫 → 定義 App Service 的計算資源。 會指定B1層中的 Linux 方案。
    • App Service → 代表您的應用程式,並在 App Service 方案中執行。
    • 虛擬網路 → 與 App Service 應用程式整合,並隔離後端網路流量。
    • Azure Database for PostgreSQL 彈性伺服器 → 只能從虛擬網路內部存取。 系統會為您在伺服器上建立資料庫和使用者。
    • 私人 DNS 區域 → 啟用虛擬網路中 PostgreSQL 伺服器的 DNS 解析。
    • Log Analytics 工作區 → 做為應用程式傳送記錄的目標容器,您也可以在其中查詢記錄。

2.使用資料庫連結字串

您使用的 azd 範本已為您產生連線變數作為應用程式設定,並輸出至終端機以方便起見。 應用程式設定是將連線秘密保留在程式碼存放庫外部的一個方法。

  1. 在 azd 輸出中,尋找應用程式設定,並尋找設定 AZURE_POSTGRESQL_CONNECTIONSTRINGAZURE_REDIS_CONNECTIONSTRING。 為了保護祕密安全,只會顯示設定名稱。 在 azd 輸出中看起來像這樣:

     App Service app has the following settings:
    
             - AZURE_POSTGRESQL_CONNECTIONSTRING
             - AZURE_REDIS_CONNECTIONSTRING
             - FLASK_DEBUG
             - SCM_DO_BUILD_DURING_DEPLOYMENT
             - SECRET_KEY
     
  2. AZURE_POSTGRESQL_CONNECTIONSTRING 包含 Azure 中 Postgres 資料庫的連接字串,AZURE_REDIS_CONNECTIONSTRING 包含 Azure 中 Redis 快取的連接字串。 您必須使用程式代碼來連線。 開啟 azureproject/production.py,取消註解下列幾行,然後儲存檔案:

    conn_str = os.environ['AZURE_POSTGRESQL_CONNECTIONSTRING']
    conn_str_params = {pair.split('=')[0]: pair.split('=')[1] for pair in conn_str.split(' ')}
    DATABASE_URI = 'postgresql+psycopg2://{dbuser}:{dbpass}@{dbhost}/{dbname}'.format(
        dbuser=conn_str_params['user'],
        dbpass=conn_str_params['password'],
        dbhost=conn_str_params['host'],
        dbname=conn_str_params['dbname']
    )
    

    您的應用程式程式代碼現在已設定為連線到 Azure 中的 PostgreSQL 資料庫。 如果您想要,請開啟 app.py,並檢視如何使用 DATABASE_URI 環境變數。

  3. 在終端機中,執行 azd deploy

    azd deploy
    

4.產生資料庫結構描述

透過受虛擬網路保護的 PostgreSQL 資料庫,執行 Flask 資料庫移轉最簡單的方式是在 SSH 工作階段搭配 App Service 容器中。

  1. 在 azd 輸出中,尋找 SSH 工作階段的 URL,並在瀏覽器中導覽至目標。 輸出中看起來像這樣:

     Open SSH session to App Service container at: https://<app-name>.scm.azurewebsites.net/webssh/host
     
  2. 在 SSH 終端機中,執行 flask db upgrade。 如果成功,App Service 已成功連線至資料庫

    A screenshot showing the commands to run in the SSH shell and their output (Flask).

    注意

    只有 /home 中檔案的變更才能在應用程式重新開機之後保存。 /home 以外的變更不會保存。

5.瀏覽至應用程式

  1. 在 azd 輸出中,尋找您應用程式的 URL,並在瀏覽器中導覽至目標。 AZD 輸出中 URL 看起來像這樣:

     Deploying services (azd deploy)
    
       (✓) Done: Deploying service web
       - Endpoint: https://<app-name>.azurewebsites.net/
     
  2. 將幾個餐廳新增至清單中。

    恭喜,您正在 Azure App Service 中執行 Web 應用程式,並安全地連線至 PostgreSQL 的適用於 PostgreSQL 的 Azure 資料庫。

6.資料流診斷記錄

Azure App Service 會擷取主控台記錄,以協助您診斷應用程式的問題。 為了方便起見,azd 範本已啟用本機檔案系統記錄,並將期傳送至 Log Analytics 工作區

如下方片段所示,樣本應用程式包含可示範這項功能的 print() 陳述式。

@app.route('/', methods=['GET'])
def index():
    print('Request for index page received')
    restaurants = Restaurant.query.all()
    return render_template('index.html', restaurants=restaurants)

在 azd 輸出中,尋找串流 App Service 記錄的連結,並在瀏覽器導覽至目標。 azd 輸出中連結看起來像這樣:

Stream App Service logs at: https://portal.azure.com/#@/resource/subscriptions/<subscription-guid>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name>/logStream

深入了解如何在設定適用於 Python 應用程式的 Azure 監視器系列中記錄 Python 應用程式。

7.清除資源

若要刪除目前部署環境中的所有 Azure 資源,請執行 azd down

azd down

疑難排解

以下列出您在嘗試完成本教學課程時可能會遇到的問題,以及解決這些問題的步驟。

我無法連線至 SSH 工作階段

如果您無法連線至 SSH 工作階段,表示應用程式本身無法啟動。 如需詳細資訊,請查看診斷記錄。 例如,如果您看到類似 KeyError: 'AZURE_POSTGRESQL_CONNECTIONSTRING' 的錯誤,這可能表示環境變數遺失 (您可能已移除應用程式設定)。

我在執行資料庫移轉時收到錯誤

如果您遇到與連線至資料庫相關的任何錯誤,請檢查應用程式設定 (AZURE_POSTGRESQL_CONNECTIONSTRING) 是否遭到變更。 若未完成那份連結字串,移轉命令就無法與資料庫通訊。

常見問題集

這設定會產生多少費用?

建立資源的定價如下:

  • App Service 方案是在基本層中建立,並可擴大或縮小。 請參閱 App Service 定價
  • PostgreSQL 彈性伺服器是在最低的高載層 Standard_B1ms 中建立,搭配最少的儲存體大小,儲存體大小可以相應增加或減少。 請參閱 Azure PostgreSQL Database 定價
  • 除非您設定額外的功能 (例如對等互連),否則虛擬網路不會產生費用。 請參閱 Azure 虛擬網路定價
  • 私人 DNS 區域會產生少量費用。 請參閱 Azure DNS 定價

如何使用其他工具連線至虛擬網路後方受保護的 PostgreSQL 伺服器?

  • 若要從命令列工具進行基本存取,您可以從應用程式的 SSH 終端機執行 psql
  • 若要從桌面工具連線,您的電腦必須位於虛擬網路內。 例如,該電腦可以是連線到其中一個子網路的 Azure VM,或內部部署網路中具有與 Azure 虛擬網路站對站 VPN 連線的電腦。
  • 您也可以將 Azure Cloud Shell 與虛擬網路整合

本機應用程式開發如何與 GitHub Actions 搭配運作?

使用 App Service 自動產生的工作流程檔案為例,每個 git push 都會開始執行新的組建和部署。 從 GitHub 存放庫的本機複本,並將所需的更新推送至 GitHub。 例如:

git add .
git commit -m "<some-message>"
git push origin main

如何設定 Django 範例以在 Azure App Service 上執行?

注意

如果您使用自己的應用程式遵循本教學課程,請查看每個專案 README.md 檔案 (FlaskDjango) 中 requirements.txt 檔案描述以查看您需要的套件。

Django 範例應用程式會設定在 azureproject/production.py 檔案中的設定,使其可在 Azure App Service 中執行。 這些變更常見於將 Django 部署到生產環境時,而非 App Service 特有。

  • Django 會驗證連入要求中的 HTTP_HOST 標頭。 範例程式碼使用 App Service 中的 WEBSITE_HOSTNAME 環境變數,將應用程式的網域名稱新增至 Django 的 ALLOWED_HOSTS 設定。

    # Configure the domain name using the environment variable
    # that Azure automatically creates for us.
    ALLOWED_HOSTS = [os.environ['WEBSITE_HOSTNAME']] if 'WEBSITE_HOSTNAME' in os.environ else []
    
  • Django 不支援在生產環境中提供靜態檔案。 在本教學課程中,您會使用 WhiteNoise 來提供檔案。 已安裝 WhiteNoise 套件及 requirements.txt,其中介軟體已新增至清單。

    
    # WhiteNoise configuration
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        # Add whitenoise middleware after the security middleware
        'whitenoise.middleware.WhiteNoiseMiddleware',
    

    然後,會根據 Django 文件設定靜態檔案設定。

    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
    

如需詳細資訊,請參閱 Django 應用程式的生產設定

下一步

前進到下一個教學課程,以了解如何使用自訂網域和憑證保障您的應用程式。

了解 App Service 如何執行 Python 應用程式: