共用方式為


教學課程:使用 Azure Container Apps 和 PostgreSQL 建置和部署 Python Web 應用程式

本文是教學課程系列的一部分,說明如何將 Python Web 應用程式容器化和部署至 azure Container Apps。 Container Apps 可讓您部署容器化應用程式,而不需要管理複雜的基礎結構。

在本教學課程中,您會:

  • 在雲端中建置容器映像,以容器化 Python 範例 Web 應用程式 (Django 或 Flask)。
  • 將容器映像部署至 Azure Container Apps。
  • 定義環境變數,讓容器應用程式能夠連線到 適用於PostgreSQL的 Azure 資料庫 - 彈性伺服器 實例,其中範例應用程式會儲存數據。

下圖醒目提示本教學課程中的工作:建置和部署容器映像。

展示在 Azure Container Apps 上部署 Python 應用程式時所涉及服務的圖表,其中重點標出手動建置映像的部分。

先決條件

如果您沒有 Azure 訂用帳戶,請在開始之前建立 免費帳戶

您可以在 Azure Cloud Shell 或已安裝 azure CLI 的工作站上執行 Azure CLI 命令。

如果您在本機執行,請遵循下列步驟來登入並安裝本教學課程的必要模組:

  1. 如有必要,請登入 Azure 並進行驗證:

    az login
    
  2. 請確定您執行的是最新版的 Azure CLI:

    az upgrade
    
  3. 使用 az extension add 命令,安裝或升級 containerapprdbms-connect 的 Azure CLI 擴充功能:

    az extension add --name containerapp --upgrade
    az extension add --name rdbms-connect --upgrade
    

    注意

    若要列出安裝在系統上的擴充功能,您可以使用 az extension list 命令。 例如:

    az extension list --query [].name --output tsv
    

取得範例應用程式

將範例程式碼派生並克隆至您的開發環境:

  1. 移至範例應用程式的 GitHub 存放庫(DjangoFlask),然後選取 [分支]。

    請按照以下步驟將儲存庫分叉到你的 GitHub 帳戶中。 您也可以不需要復刻或 GitHub 帳戶,直接將代碼庫下載到本地電腦。 但是,如果您使用下載方法,您將無法在本系列下一個教學課程中設定持續整合和持續傳遞(CI/CD)。

  2. 使用 git clone 命令,將分支存放庫複製到 python-container 資料夾:

    # Django
    git clone https://github.com/$USERNAME/msdocs-python-django-azure-container-apps.git python-container
    
    # Flask
    # git clone https://github.com/$USERNAME/msdocs-python-flask-azure-container-apps.git python-container
    
  3. 變更目錄:

    cd python-container
    

從 Web 應用程式程式代碼建置容器映像

遵循這些步驟之後,您將有一個 Azure Container Registry 實例,其中包含從範例程式代碼建置的 Docker 容器映射。

  1. 使用 az group create 命令 建立資源群組:

    az group create \
        --name pythoncontainer-rg \
        --location <location>
    

    <> 的位置取代為命令 az account list-locations -o table輸出的 Azure 位置 Name 值之一。

  2. 使用命令 az acr create 來建立容器註冊表。

    az acr create \
        --resource-group pythoncontainer-rg \
        --name <registry-name> \
        --sku Basic \
        --admin-enabled
    

    您用於 <登錄名稱> 的名稱在 Azure 中必須是唯一的,而且必須包含 5 到 50 個英數位元。

  3. 使用 az acr login 命令登入至登錄處。

    az acr login --name <registry-name>
    

    命令會將 「azurecr.io」 新增至名稱,以建立完整登錄名稱。 如果登入成功,會出現「登入成功」訊息。 如果您要從不同於建立登錄的訂用帳戶來存取登錄,請使用 --suffix 開關。

    如果登入失敗,請確定 Docker 精靈正在您的系統上執行。

  4. 使用 az acr build 命令建置映像:

    az acr build \
        --registry <registry-name> \
        --resource-group pythoncontainer-rg \
        --image pythoncontainer:latest .
    

    這些考慮適用於:

    • 命令結尾的點 (.) 表示要建置的原始碼位置。 如果您未在範例應用程式的根目錄中執行此命令,請指定程式代碼的路徑。

    • 如果您在 Azure Cloud Shell 中執行 命令,請使用 git clone 先將存放庫提取到 Cloud Shell 環境中。 然後將目錄切換到專案的根目錄,以便正確解釋點(.)。

    • 如果您省略 [ -t 相同 --image] 選項,命令會將本機內容組建排入佇列,而不會將它推送至登錄。 在沒有推送的情況下建置對於檢查映像是否建置很有用。

  5. 使用 az acr repository list 命令確認容器映像已創建:

    az acr repository list --name <registry-name>
    

注意

本節中的步驟會在基本服務層級中建立容器登錄。 此層是成本優化的,擁有為開發人員的使用情境而設計的功能集和吞吐量,並且符合本教學課程需求。 在生產場景中,您很可能會使用標準或進階服務層級。 這些層級提供增強的儲存和吞吐量。

若要深入瞭解,請參閱 Azure Container Registry 服務層級。 如需定價資訊,請參閱 Azure Container Registry 定價

建立 PostgreSQL 彈性伺服器實例

範例應用程式 (DjangoFlask) 會將餐廳檢閱資料儲存在 PostgreSQL 資料庫中。 在這些步驟中,您會建立將包含資料庫的伺服器。

  1. 使用 az postgres flexible-server create 命令在 Azure 中建立 PostgreSQL 伺服器。 此命令在完成前執行幾分鐘並不罕見。

    az postgres flexible-server create \
       --resource-group pythoncontainer-rg \
       --name <postgres-server-name>  \
       --location <location> \
       --admin-user demoadmin \
       --admin-password <admin-password> \
       --active-directory-auth Enabled \
       --tier burstable \
       --sku-name standard_b1ms \
       --public-access 0.0.0.0 
    

    使用這些值:

    • pythoncontainer-rg:本教學課程使用的資源組名。 如果您使用不同的名稱,請變更此值。

    • <postgres-server-name>:PostgreSQL 資料庫伺服器名稱。 此名稱在所有 Azure 中都必須是唯一的。 伺服器的端點是 https://<postgres-server-name>.postgres.database.azure.com。 允許的字元是AZ09,以及連字號(-)。

    • <位置>:使用您用於 Web 應用程式的相同位置。 <位置> 是從命令 az account list-locations -o table的輸出中取得的 Azure 位置值 Name 之一。

    • <admin-username>:系統管理員帳戶的用戶名稱。 它不能 azure_superuseradminadministratorrootguestpublic。 請使用 demoadmin 進行此教學。

    • <系統管理員密碼>:系統管理員用戶的密碼。 其必須包含 8 到 128 個字元,且來自下列類別的其中三個類別:英文大寫字母、英文小寫字母、數字及非英數字元。

      重要

      當您建立使用者名稱或密碼時,不會 使用貨幣符號 ($) 字元。 稍後,當您使用這些值建立環境變數時,該字元在用來執行 Python 應用程式的 Linux 容器中具有特殊意義。

    • --active-directory-auth:這個值會指定是否在 PostgreSQL 伺服器上啟用Microsoft Entra 驗證。 將它設定為 Enabled

    • --sku-name:定價層和計算組態的名稱;例如,Standard_B1ms。 如需詳細資訊,請參閱適用於 PostgreSQL 的 Azure 資料庫定價。 若要列出可用的層,請使用 az postgres flexible-server list-skus --location <location>

    • --public-access:使用 0.0.0.0。 它允許從任何 Azure 服務公開存取伺服器,例如 Container Apps。

    注意

    如果您計劃從本機工作站使用工具來操作 PostgreSQL 伺服器,則需要使用 az postgres flexible-server firewall-rule create 命令,為本機工作站的 IP 位址新增防火牆規則。

  2. 使用 az ad signed-in-user show 命令來取得使用者帳戶的物件識別符。 您會在下一個命令中使用這個識別碼。

    az ad signed-in-user show --query id --output tsv
    
  3. 使用 az postgres flexible-server ad-admin create 命令,將您的使用者帳戶新增為 PostgreSQL 伺服器上的 Microsoft Entra 系統管理員:

    az postgres flexible-server ad-admin create \
       --resource-group pythoncontainer-rg \
       --server-name <postgres-server-name>  \
       --display-name <your-email-address> \
       --object-id <your-account-object-id>
    

    針對您的帳戶物件標識碼,請使用您在上一個步驟中取得的值。

注意

本節中的步驟會在高載定價層中建立具有單一虛擬核心和有限記憶體的 PostgreSQL 伺服器。 彈性階層是一個較低成本的選擇,適用於不需要持續使用全部 CPU 的工作負載,並適合本教學課程的需求。 針對生產工作負載,您可以升級至一般用途或記憶體優化定價層。 這些層級可提供更高的效能,但會增加成本。

若要深入瞭解,請參閱適用於 PostgreSQL 的 Azure 資料庫中 計算選項 - 彈性伺服器。 如需定價的相關信息,請參閱 Azure PostgreSQL 資料庫的定價

在伺服器上建立資料庫

此時,您有 PostgreSQL 伺服器。 在本節中,您會在伺服器上建立資料庫。

使用 az postgres flexible-server db create 命令來建立名為 restaurants_reviews的資料庫:

az postgres flexible-server db create \
   --resource-group pythoncontainer-rg \
   --server-name <postgres-server-name> \
   --database-name restaurants_reviews

使用這些值:

  • pythoncontainer-rg:本教學課程使用的資源組名。 如果您使用不同的名稱,請變更此值。
  • <postgres-server-name>:PostgreSQL 伺服器的名稱。

您也可以使用 az postgres flexible-server connect 命令來連線到資料庫,然後使用 psql 命令。 當您使用 psql 時,通常使用 Azure Cloud Shell 會更容易,因為這個 Shell 已經包含了所有所需的相依套件。

您也可以連線到適用於 PostgreSQL 的 Azure 資料庫彈性伺服器,並使用 psql 或支援 PostgreSQL 的 IDE 來建立資料庫,例如 Azure Data Studio。 如需使用 psql 的步驟,請參閱本文稍後的 在 PostgreSQL 資料庫上設定受控識別

建立使用者指派的受控識別

建立使用者指派的受控識別,以在 Azure 中執行時作為容器應用程式的身分識別。

注意

若要建立使用者指派的受控識別,您的帳戶需要 受控識別提供者 角色指派。

使用 az identity create 命令來建立使用者指派的受控識別 (即受管理的身分識別):

az identity create --name my-ua-managed-id --resource-group pythoncontainer-rg

在 PostgreSQL 資料庫上設定受控識別

將受控識別設定為 PostgreSQL 伺服器上的角色,然後將 restaurants_reviews 資料庫的必要許可權授與它。 無論您是使用 Azure CLI 或 psql,您都必須使用已被設定為伺服器實例上 Microsoft Entra 系統管理員的使用者連線到 Azure PostgreSQL 伺服器。 只有配置為 PostgreSQL 系統管理員的 Microsoft Entra 帳戶,才能在您的伺服器上設定受控的身份和其他 Microsoft 系統管理員角色。

  1. 使用 az account get-access-token 命令來取得 Azure 帳戶的存取令牌。 您在後續步驟中使用存取令牌。

    az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken
    

    傳回的令牌很長。 在環境變數中設定其值,以在下一個步驟的命令中使用:

    MY_ACCESS_TOKEN=<your-access-token>
    
  2. 使用 az postgres flexible-server execute 命令,將使用者指派的受控識別新增為您的 PostgreSQL 伺服器上的資料庫角色:

    az postgres flexible-server execute \
        --name <postgres-server-name> \
        --database-name postgres \
        --querytext "select * from pgaadauth_create_principal('"my-ua-managed-id"', false, false);select * from pgaadauth_list_principals(false);" \
        --admin-user <your-Azure-account-email> \
        --admin-password $MY_ACCESS_TOKEN
    

    使用這些值:

    • 如果您針對受控識別使用不同的名稱,請將 pgaadauth_create_principal 命令中的 my-ua-managed-id 取代為受控識別的名稱。

    • 針對 --admin-user 值,請使用與您 Azure 帳戶相關的電子郵件地址。

    • 請使用先前命令輸出的存取令牌作為 --admin-password 值,不需加上引號。

    • 請確定資料庫名稱 postgres

    注意

    如果您要在本機工作站上執行 az postgres flexible-server execute 命令,請確定您已為工作站的 IP 位址新增防火牆規則。 您可以使用 az postgres flexible-server firewall-rule create 命令來新增規則。 下一步中的命令也有相同的需求。

  3. 使用下列 az postgres flexible-server execute 命令,將 restaurants_reviews 資料庫的必要許可權授與使用者指派的受控識別:

    az postgres flexible-server execute \
        --name <postgres-server-name> \
        --database-name restaurants_reviews \
        --querytext "GRANT CONNECT ON DATABASE restaurants_reviews TO \"my-ua-managed-id\";GRANT USAGE ON SCHEMA public TO \"my-ua-managed-id\";GRANT CREATE ON SCHEMA public TO \"my-ua-managed-id\";GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"my-ua-managed-id\";ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO \"my-ua-managed-id\";" \
        --admin-user <your-Azure-account-email> \
        --admin-password $MY_ACCESS_TOKEN
    

    使用這些值:

    • 如果您針對受控識別使用不同的名稱,請將 命令中的所有 my-ua-managed-id 實例取代為受控識別的名稱。 查詢字串中有五個實例。

    • 針對 --admin-user 值,請使用 Azure 帳戶的電子郵件位址。

    • 針對 --admin-password 值,請使用先前輸出結果中的存取權杖,並且不要加上引號。

    • 請確定資料庫名稱 restaurants_reviews

    此 Azure CLI 命令會連線到伺服器上的 restaurants_reviews 資料庫,併發出下列 SQL 命令:

    GRANT CONNECT ON DATABASE restaurants_reviews TO "my-ua-managed-id";
    GRANT USAGE ON SCHEMA public TO "my-ua-managed-id";
    GRANT CREATE ON SCHEMA public TO "my-ua-managed-id";
    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "my-ua-managed-id";
    ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "my-ua-managed-id";
    

將 Web 應用程式部署至容器應用程式

容器應用程式會部署至 Azure Container Apps 環境,其可作為安全界限。 在下列步驟中,您會先建立環境,然後在該環境中建立一個容器。 接著,您可以設定容器,讓網站在外部可見。

這些步驟需要 Azure Container Apps 擴充功能,containerapp

  1. 使用 az containerapp env create 命令建立 Container Apps 環境:

    az containerapp env create \
    --name python-container-env \
    --resource-group pythoncontainer-rg \
    --location <location>
    

    <位置> 是命令輸出 az account list-locations -o table的其中一個 Azure 位置 Name 值。

  2. 使用 az acr credential show 命令,取得 Azure Container Registry 實例的登入認證:

    az acr credential show -n <registry-name>
    

    當您在步驟 5 中建立容器應用程式時,您會使用命令輸出中傳回的使用者名稱和其中一個密碼。

  3. 使用 az identity show 命令來獲取用戶指派的受控識別的客戶端識別碼和資源識別碼:

    az identity show --name my-ua-managed-id --resource-group pythoncontainer-rg --query "[clientId, id]" --output tsv
    

    當您在步驟 5 中建立容器應用程式時,您會使用命令輸出中的用戶端識別元 (GUID) 值和資源識別碼。 資源識別碼的格式如下:/subscriptions/<subscription-id>/resourcegroups/pythoncontainer-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-ua-managed-id

  4. 執行下列命令來產生秘密金鑰值:

    python -c 'import secrets; print(secrets.token_hex())'
    

    當您在步驟 5 中建立容器應用程式時,您可以使用秘密金鑰值來設定環境變數。

    注意

    此步驟顯示的命令適用於 Bash Shell。 視您的環境而定,您可能需要使用 python3叫用 Python。 在 Windows 上,您必須以雙引弧括住 -c 參數中的命令,而不是單引號。 視您的環境而定,您可能也需要使用 pypy -3叫用 Python。

  5. 在環境中使用 az containerapp create 命令建立容器應用程式。

    az containerapp create \
    --name python-container-app \
    --resource-group pythoncontainer-rg \
    --image <registry-name>.azurecr.io/pythoncontainer:latest \
    --environment python-container-env \
    --ingress external \
    --target-port <5000 for Flask or 8000 for Django> \
    --registry-server <registry-name>.azurecr.io \
    --registry-username <registry-username> \
    --registry-password <registry-password> \
    --user-assigned <managed-identity-resource-id> \
    --query properties.configuration.ingress.fqdn \
    --env-vars DBHOST="<postgres-server-name>" \
    DBNAME="restaurants_reviews" \
    DBUSER="my-ua-managed-id" \
    RUNNING_IN_PRODUCTION="1" \
    AZURE_CLIENT_ID="<managed-identity-client-id>" \
    AZURE_SECRET_KEY="<your-secret-key>"
    

    請務必將角括號中的所有值替換為您在本教程中使用的值。 請注意,容器應用程式的名稱在整個 Azure 中必須是唯一的。

    --env-vars 參數的值是由 key=“value” 格式中的空格分隔值所組成的字串,具有下列值:

    • DBHOST="\<postgres-server-name>"
    • DBNAME="restaurants_reviews"
    • DBUSER="my-ua-managed-id"
    • RUNNING_IN_PRODUCTION="1"
    • AZURE_CLIENT_ID="\<managed-identity-client-id>"
    • AZURE_SECRET_KEY="\<your-secret-key>"

    DBUSER 的值是您使用者指派的受控識別名稱。

    AZURE_CLIENT_ID 的值是使用者指派受控識別的用戶端標識碼。 您在上一個步驟中取得此值。

    AZURE_SECRET_KEY 的值是您在上一個步驟中產生的秘密密鑰值。

  6. 僅限 Django,請移轉並建立資料庫架構。 (在 Flask 範例應用程式中,它會自動完成,您可以略過此步驟。

    使用 az containerapp exec 命令連線:

        az containerapp exec \
            --name python-container-app \
            --resource-group pythoncontainer-rg
    

    然後,在shell指令提示字元中,輸入python manage.py migrate

    您不需要移轉容器的修訂。

  7. 測試網站。

    您先前輸入的 az containerapp create 命令將輸出一個應用程式網址,您可以用來訪問該應用程式。 URL 結尾為 azurecontainerapps.io。 在瀏覽器中打開該 URL。 或者,您可以使用 az containerapp browse 命令。

新增餐廳和兩個評論後,這是範例網站的一個示例。

本教學課程中建置之範例網站的螢幕快照。

針對部署進行疑難排解

您忘記應用程式 URL 來存取網站

在 Azure 入口網站中:

  • 移至容器應用程式的 [概觀] 頁面,並尋找 應用程式 URL

在 VS Code 中:

  1. 移至 Azure 檢視 (Ctrl+Shift+A),然後展開您正在使用的訂用帳戶。
  2. 展開 [Container Apps] 節點,展開受控環境,以滑鼠右鍵點擊 python-container-app,然後選取 [瀏覽]。 VS Code 會使用應用程式 URL 開啟瀏覽器。

在 Azure CLI 中:

  • 使用命令 az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn

在 VS Code 中,Azure 任務執行建置映像檔時會傳回錯誤

如果您看到「錯誤:無法下載內容」訊息。 請檢查 VS Code 輸出 視窗中的 URL 是否不正確,然後於 Docker 擴充功能中更新登錄。 若要重新整理,請選取 Docker 擴充功能,移至 登錄 區段,找到註冊表,然後選取它。

如果您在 Azure 工作中再次執行 建置映射,請檢查先前執行中的登錄是否存在。 如果是,請使用它。

在 Azure 入口網站中,建立容器應用程式期間會出現存取錯誤

在停用 Azure Container Registry 實例上的系統管理員認證時,會發生包含「無法存取 ACR '<名稱>.azurecr.io』」 的存取錯誤。

若要在入口網站中檢查系統管理員狀態,請移至您的 Azure Container Registry 實例,選取 存取密鑰 資源,並確定已啟用 系統管理員使用者

您的容器映像不會出現在 Azure Container Registry 實例中

  • 檢查 Azure CLI 命令或 VS Code 的輸出,並尋找訊息以確認成功。
  • 使用 Azure CLI 或 VS Code 工作提示,檢查您的組建命令中已正確指定登錄的名稱。
  • 請確定您的認證未過期。 例如,在 VS Code 中,在 Docker 擴充功能中尋找目標登錄並重新整理。 在 Azure CLI 中,執行 az login

網站顯示「錯誤請求(400)」

如果您收到「不正確的要求(400)」錯誤,請檢查傳入容器的PostgreSQL環境變數。 400 錯誤通常表示 Python 程式代碼無法連線到 PostgreSQL 實例。

本教學課程中使用的範例程式代碼會檢查容器環境變數是否存在 RUNNING_IN_PRODUCTION,它可以設定為任何值(例如 1)。

網站傳回「找不到」(404)」

  • 檢查容器 概觀 頁面上 應用程式 URL 值。 如果應用程式 URL 包含「internal」這個字,則入口設定不正確。
  • 檢查容器的輸入。 例如,在 Azure 入口網站中,前往容器的 入口 資源。 請確定已啟用 HTTP 入口,並選擇 [接受來自任何位置的流量]。

網站未啟動,您會收到「串流超時」提示,或沒有任何回應。

  • 檢查記錄:
    • 在 Azure 入口網站中,移至容器應用程式的修訂管理資源,並檢查容器 布建狀態
      • 如果狀態 配置中,請等候配置完成。
      • 如果狀態為 失敗,請選取修訂並檢視主控台日誌。 選擇顯示 產生時間Stream_sLog_s的欄位順序。 依最新記錄排序,並尋找 Stream_s 數據行中的 Python stderrstdout 訊息。 Python print 輸出 stdout 訊息。
    • 在 Azure CLI 中,使用 az containerapp logs show 命令
  • 如果您使用 Django 架構,請檢查資料庫中是否有 restaurants_reviews 數據表。 如果沒有,請使用主控台來存取容器並執行 python manage.py migrate

後續步驟