Azure 的 Docker Compose 設定將淘汰。多重容器支援,請更新為 Sidecar (側邊欄容器)

官方說明文件: Migrate Docker Compose apps to sidecars in Azure App Service
https://learn.microsoft.com/en-us/azure/app-service/migrate-sidecar-multi-container-apps

這是因為 Azure App Service 正式宣佈將於 2027 年淘汰對 Docker Compose (Multi-container) 的支援,轉而推廣使用 Sidecar (側邊欄容器) 架構。

這對你目前的影響是,雖然現在還能用,但未來的標準做法會改變。以下是針對這項異動的說明與應對方式。

為什麼 Azure 要淘汰 Docker Compose

Azure 原本的 Web App for Containers 支援上傳一個 docker-compose.yml 來跑多個服務,但這種模式在擴展性、網路隔離與日誌管理上受限較多。Sidecar 模式是目前雲端原生(如 Kubernetes)的主流標準,它允許一個主應用程式(如你的 Backend)搭配多個輔助容器(如記錄處理、快取或前端靜態服務)。

針對你的專案建議做法

你的專案包含 backendfrontend,在 Sidecar 模式下,結構會變成:

  • 主容器 (Main Container):通常是你的後端服務 (FastAPI)。
  • Sidecar 容器:你的前端服務。

如何更新為 Sidecar 支援

如果你現在想提早轉移,或者建立新的資源,你需要改用以下邏輯部署:

  1. 建立主容器先建立一個基本的 Web App 並指向你的後端映像檔:

PowerShell

az webapp create --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --plan $PLAN_NAME --deployment-container-image-name "$ACR_NAME.azurecr.io/backend:latest"
  1. 新增 Sidecar 容器 (前端)使用 az webapp container sidecar add 指令將前端掛載上去:

PowerShell

az webapp container sidecar add `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --container-name frontend-sidecar `
  --image "$ACR_NAME.azurecr.io/frontend:latest" `
  --port 3000

兩者的主要差異

  • 網路通訊:在 Docker Compose 中,你可能習慣用服務名稱(如 http://backend:8000)通訊。在 Sidecar 模式中,所有容器共享同一個 localhost,所以前端呼叫後端可以改用 http://localhost:8000
  • 資源分配:你可以分別為每個 Sidecar 容器設定 CPU 與記憶體限制,這比 Docker Compose 更有彈性。

我該現在換嗎

目前的警告只是預告,距離 2027 年還有時間。如果你目前的 docker-compose.yml 運作正常,且急著上線,可以先忽略此警告。但如果你正在進行新的架構設計,建議直接改用 Sidecar 或是考慮搬遷到 Azure Container Apps (ACA),後者對多容器的支援比 Web App 更完整且強大。


把目前的 docker-compose.yml 邏輯完整轉化為 Sidecar 部署腳本

既然你決定採用新的 Sidecar (側邊欄容器) 架構,這是一個更符合雲端原生標準的做法。在這種模式下,主容器與 Sidecar 容器會共享同一個網路命名空間,也就是說它們可以透過 localhost 互相通訊。

以下是將你原本的 docker-compose.yml 邏輯轉換為 Azure Sidecar 部署的完整 PowerShell 步驟:

1. 準備環境變數與資源

請確保你的 App Service Plan 是 Linux 且等級在 Basic (B1) 以上,因為 Free/Shared 層級不支援自訂容器。

PowerShell

$ACR_NAME = "arcpolicyrecommendationfastapi001"
$RESOURCE_GROUP = "rg-spoke-policyrecommendation-prod-twnt-001"
$WEB_APP_NAME = "policy-recommendation-fast"
$PLAN_NAME = "你的AppServicePlan名稱" # 請替換為實際名稱

2. 建立主容器 (以 Backend 為主)

我們首先建立 Web App 本體,並將後端 API 作為主要運行的容器。

PowerShell

# 建立 Web App 並指向後端映像檔
az webapp create `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --plan $PLAN_NAME `
  --deployment-container-image-name "$ACR_NAME.azurecr.io/backend:latest"

3. 設定受控識別與權限

延續你之前的安全做法,讓 Web App 有權限拉取 ACR 映像檔。

PowerShell

# 啟用識別並取得 ID
$MSI_ID = az webapp identity assign --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --query principalId --output tsv

# 取得 ACR 資源 ID 並授權
$ACR_ID = az acr show --name $ACR_NAME --query id --output tsv
az role assignment create --assignee $MSI_ID --scope $ACR_ID --role acrpull

# 開啟受控識別拉取開關
az webapp config set --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP `
  --generic-configurations '{\"acrUseManagedIdentityCreds\": true}'

4. 新增 Sidecar 容器 (Frontend)

現在將前端作為 Sidecar 掛載上去。注意這裡的 --port 是前端容器內部監聽的埠號。

PowerShell

az webapp container sidecar add `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --container-name frontend-sidecar `
  --image "$ACR_NAME.azurecr.io/frontend:latest" `
  --port 3000

5. 調整連線邏輯與重啟

在 Sidecar 架構下,有幾個重要的改變:

  • 連線方式:前端如果要呼叫後端 API,在程式碼中原本可能是指向 http://backend:8000,現在請改為 http://localhost:8000
  • 環境變數:如果需要為特定容器設定環境變數,可以使用 az webapp config appsettings set,這些變數會被所有容器共享。

最後,重啟 Web App 讓設定生效:

PowerShell

az webapp restart --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP

驗證 Sidecar 狀態

你可以使用以下指令查看 Sidecar 是否已成功掛載並運行:

PowerShell

az webapp container sidecar list --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP

這是一個非常關鍵的觀察。在 Azure App Service 的 Sidecar 模式中,網路行為與傳統的 Docker Compose 確實有一點不同,特別是在「對外暴露」的部分。

只有一個進入點 (Port 80/443)

Azure App Service 的設計是為了託管「一個」主要的 Web 應用程式。即使你掛載了 Sidecar,外部流量(來自瀏覽器或 Postman)預設只能抵達 Main Container (主容器) 所監聽的埠號。

  • 主容器 (Backend):如果它監聽 8000,Azure 會自動把外部的 80/443 流量導向它。你可以從外部測試它。
  • Sidecar 容器 (Frontend):雖然它也在跑,但它躲在主容器後面。如果你從外部瀏覽器輸入 https://your-app.azurewebsites.net:3000,這會被擋掉,因為 Azure 的負載平衡器通常不開放 3000 埠給外部。

如何解決連線與測試問題?

根據你的架構,通常有兩種常見的處理方式:

1. 讓 Backend 成為反向代理 (推薦)

你可以讓 FastAPI (Backend) 處理所有的 API 請求,並透過程式碼或特定的路由將靜態頁面的請求轉發給前端容器。但在 Sidecar 模式下,更常見的是前端呼叫後端

2. 透過 Localhost 互相通訊 (Sidecar 的優勢)

Sidecar 最大的好處是它們共享 Network Namespace

  • 前端呼叫後端:前端程式碼(如果是 Server-side rendering)可以直接存取 http://localhost:8000
  • 後端呼叫前端:後端也可以存取 http://localhost:3000

測試 Backend API 是否被擋?

如果你想從本地電腦(外部)測試部署在 Azure 上的 Backend API,請確認以下幾點:

  1. WEBSITES_PORT 設定:在 Web App 的「設定」>「環境變數」中,新增一個 WEBSITES_PORT,數值設為 8000(或是你 Backend 監聽的埠)。這會告訴 Azure 把外部請求導向後端容器。
  2. CORS 問題:如果你的前端是 React/Vue 並且在使用者瀏覽器執行,它去呼叫 Azure API 時可能會被瀏覽器的 CORS 政策擋住。請在 FastAPI 中加入:Pythonfrom fastapi.middleware.cors import CORSMiddleware app.add_middleware(CORSMiddleware, allow_origins=["*"], ...)
  3. 使用 Web App 內建的 SSH/Log Stream:如果你懷疑容器內部通訊有問題,可以去 Azure Portal 找到 SSH 工具進入容器。在裡面執行 curl http://localhost:8000/health。如果內部能通但外部不能通,那就是 Azure 網路層(防火牆或埠號映射)的問題。

總結

Sidecar 本身不會「擋」掉通訊,它反而讓內部通訊變得像在同一台電腦一樣簡單。會被擋掉的通常是從你家電腦直接連到 Sidecar 容器的特定埠號

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *