
Demo 資料說明
本文是一篇教學用範例。Example Company、
demoproject、Azure 資源名稱、帳號、網域與 tenant 都是虛構資料,不能直接拿來連線或部署。實際使用時,請替換成自己的環境設定。
先說結論
Example Company 的開發團隊想在 Azure Container Apps 裡快速展示 Backend 功能,但暫時不需要使用既有的 Azure SQL Database,也不需要讀取既有的 demoproject-dev 資料。
這種情況可以在同一個 Container Apps Environment 裡,另外部署一個暫時的 Microsoft SQL Server container,提供一個全新的 Demo database。
這個方案的重點是:
- Demo SQL Server 是獨立的新資料庫。
- Backend 不連既有的
demoproject-dev。 - 不匯入正式或 staging 資料。
- 不使用既有 Azure SQL 的 Managed Identity、contained user 或 database roles。
- Backend、MSSQL 和 Frontend 仍然要正確設定網路、secret、storage、health check 和 CI/CD。
換句話說,這不是把原本的 Azure SQL 搬進 container,而是建立一套隔離、短期、只供 Demo 使用的資料庫環境。
為什麼需要這個方案?
假設目前的開發環境是:
cae-example-dev-001
這個 Environment 主要用來執行開發中的 Container App,但沒有連到既有 Azure SQL Private Endpoint 所需的完整 VNet 路徑。
如果 Backend 直接使用 Azure SQL,可能會遇到:
- SQL network connection timeout。
- Private Endpoint 無法連線。
- Azure SQL firewall 拒絕來源 IP。
- Managed Identity 可以取得 token,但 SQL database 沒有對應的 user 或 roles。
可是,這次 Demo 的需求並不是要存取既有資料,而是希望先讓團隊能夠:
- 啟動 Backend API。
- 建立一些測試資料。
- 展示查詢、新增、修改等基本功能。
- 讓 Frontend 能呼叫 Backend。
因此,可以把資料庫改成和 Backend 位於同一個 Container Apps Environment 的內部 MSSQL App,讓這次 Demo 不依賴既有 Azure SQL 的 Private Endpoint。
目標架構
Demo 環境可以設計成下面這樣:
Frontend 或測試工具
│
▼
ca-example-backend-dev-001
│ internal connection
▼
ca-example-mssql-demo-dev-001
│ TCP 1433,僅限 internal ingress
▼
demoproject-demo
示範資源如下:
| 元件 | Demo 名稱 | 用途 |
|---|---|---|
| Container Apps Environment | cae-example-dev-001 | 執行所有 Demo App |
| Backend App | ca-example-backend-dev-001 | 提供 API |
| MSSQL App | ca-example-mssql-demo-dev-001 | 提供 Demo database |
| Database | demoproject-demo | 全新、隔離的測試資料 |
| Resource Group | rg-demo-dev-001 | 存放 Demo Container Apps |
MSSQL 應該是獨立的 Container App,不要和 Backend 放在同一個 container。這樣可以分別更新 Backend 和資料庫,也比較容易在 Demo 結束時清理。
需要怎麼做?
第一步:建立獨立的 MSSQL Container App
使用官方 Microsoft SQL Server Linux container image,並固定版本或 digest,不要長期使用會隨時間變動的 latest tag。
MSSQL App 的基本設定應包含:
App name: ca-example-mssql-demo-dev-001
Environment: cae-example-dev-001
Port: TCP 1433
Ingress: internal only
Database: demoproject-demo
Container 需要設定:
ACCEPT_EULA=YMSSQL_PID=DeveloperMSSQL_SA_PASSWORD- 足夠的 CPU 和 memory
- TCP
1433target port - readiness/startup health check
SQL Server container 通常至少需要 2 GiB memory;Demo 建議依實際啟動時間與資料量配置更多資源。
MSSQL_PID=Developer 只適合非正式 Demo,不能當成 production license 或正式 staging database。SA password 不可以寫在 Dockerfile、image、repository 或 workflow 明文中。
第二步:只開放內部網路
MSSQL App 只能使用 internal ingress:
Backend App ── internal DNS ──> MSSQL App:1433
不要把 SQL Server 的 TCP 1433 開成 public ingress,也不要讓測試人員直接從 Internet 連入。
Backend 和 MSSQL App 最簡單的做法是放在同一個 cae-example-dev-001。Backend 使用 MSSQL App 的 internal FQDN 連線,不要自行猜測 FQDN 格式,應從 Azure Container Apps 的 App 設定或 DNS 設定取得實際值。
第三步:建立專用 application login
Backend 不應使用 sa 登入。MSSQL container 第一次啟動後,應執行一次初始化流程:
- 建立
demoproject-demodatabase。 - 建立專用的 Backend application login。
- 只授予 application login 必要的 read/write 權限。
- 只有需要執行 schema migration 時,才授予有限的 DDL 權限。
- 確認 Backend 不會取得 SA password。
這個 Demo SQL Server 是獨立的 SQL container,Backend 通常會使用 SQL login/password,而不是既有 Azure SQL 的 Microsoft Entra Managed Identity flow。
因此,application login 的 username 和 password 必須放在 Container App secret 或 Key Vault secret reference 中,不能放在 source code 或公開設定檔。
第四步:修改 Backend 的 connection string
Backend 原本如果使用 Azure SQL Managed Identity,可能會包含這類設定:
fedauth=ActiveDirectoryManagedIdentity
useMsi=true
切換到 Demo MSSQL 後,Backend 必須改成:
- SQL host:
ca-example-mssql-demo-dev-001的 internal FQDN。 - Port:
1433。 - Database:
demoproject-demo。 - Username:專用 application login。
- Password:由 secret reference 注入。
- Authentication:使用 SQL login/password。
概念上的設定如下:
sqlserver://<mssql-internal-host>:1433
?database=demoproject-demo
&user=<application-user>
&password=<secret-reference>
實際格式要依 Backend 使用的 SQL driver 調整。不要把完整 connection string 寫進 GitHub Actions log、Dockerfile 或公開的 frontend configuration。
如果 Demo SQL Server 使用 self-signed certificate,請明確決定測試環境的 TLS 設定。即使是 Demo,也不要把關閉加密或無條件信任憑證當成正式環境的解法。
第五步:建立 schema 和測試資料
全新的 demoproject-demo 不會自動有任何 table,因此需要另外準備:
- schema migration。
- 初始化 seed data。
- Demo 使用者和測試帳號。
- API 所需的 reference data。
- migration 失敗時的處理方式。
建議使用一次性的 bootstrap 或 job 初始化 database,不要讓每一個 Backend revision 在啟動時同時執行完整 migration,否則可能發生 migration race condition。
Demo data 應該是新建或去識別化資料,不要將正式資料直接複製到這個 container。
第六步:處理資料持久化
Container App 的 local filesystem 不適合當成可靠的 database storage。如果沒有持久化 volume,以下情況都可能讓資料消失:
- Container restart。
- Revision replacement。
- App 被重新建立。
- Node 或 host 發生故障。
如果 Demo 只做一次性展示,可以接受資料在環境重建後消失;如果需要保留測試結果,至少要:
- 將 SQL Server data/log 目錄掛到持久化 storage,例如 Azure Files。
- 驗證 SQL Server 在該 storage 上的 lock、I/O 和 recovery 行為。
- 設定 backup,並將 backup 放到獨立的儲存位置。
- 訂定資料保存期限。
- 確認刪除 App 或 volume 時,不會誤刪唯一一份資料。
即使使用 Azure Files,這仍然不等同於 Azure SQL Database 的 HA、backup、patching、SLA 和資料庫服務保證,所以必須把它標示為 temporary demo database。
第七步:把資料庫 bootstrap 和一般 CI/CD 分開
MSSQL App 不應該在每次 Backend push 時被刪除或重建。建議把流程分成兩部分。
一次性的 Demo bootstrap:
- 建立或更新
ca-example-mssql-demo-dev-001。 - 設定 image、secret、storage、internal ingress 和 health check。
- 等待 SQL Server ready。
- 建立
demoproject-demo、application login、schema 和 seed data。
一般 Backend CI/CD:
- 編譯 Backend。
- Push Backend image 到 ACR。
- 更新
ca-example-backend-dev-001。 - 保留 MSSQL App 和 volume,不要重新初始化 database。
Backend runtime 仍然需要自己的 ACR AcrPull。GitHub OIDC Service Principal 只負責 CI/CD 所需的 AcrPush 和 App deployment 權限,不需要 SQL database role。
如果 MSSQL image 直接從 MCR pull,必須確認 Environment 可以連到 MCR。如果團隊將 MSSQL image mirror 到 ACR,則 MSSQL App 的 runtime identity 也要另外授予 ACR AcrPull。
第八步:處理啟動順序和健康檢查
SQL Server container 通常比 API container 更久才會 ready,因此 Backend 不能假設 SQL 在啟動第一秒就能連線。
需要加入:
- MSSQL readiness/health check。
- Backend 的 connection retry 和 backoff。
- 將「SQL 尚未 ready」與「帳號密碼錯誤」分開記錄。
- SQL container restart 後,Backend 自動恢復連線。
- 避免在 logs 印出 password、完整 connection string 或 token。
az containerapp update 成功只代表 Azure 接受了 App 設定,不代表 Backend 一定已經能連到 MSSQL。必須等兩個 App 都 healthy 後,再測試 API。
Frontend 要調整什麼?
Frontend 不需要 SQL 權限,也不應取得 Backend 的 SQL credentials。
Frontend 需要確認:
- 使用正確的 Frontend image。
- 使用新的 Backend API URL。
- Nginx 或其他 web server 沒有寫死舊的 Backend hostname。
- 只有必要的 frontend secrets 被注入。
Frontend 只呼叫 Backend API;SQL connection 由 Backend 負責。
安全設定
這個 Demo 方案至少要符合以下原則:
- MSSQL App 只有 internal ingress。
- 不對 Internet 公開 TCP
1433。 - SA password 和 application password 都放在 secret。
- Backend 使用專用 application login,不使用 SA。
- 不把 SQL credentials 寫入 Git repository。
- 不讓 Frontend 取得 SQL credentials。
- 監控 container restart、CPU、memory、storage 和 backup。
- 為 Demo 設定 owner、用途和到期日。
- Demo 結束後移除 App、secret、volume 和 backup。
驗證清單
部署完成後,依照以下順序驗證:
- MSSQL App revision 是
Healthy / Running。 - Backend 可以解析 MSSQL App 的 internal FQDN。
- Backend 可以建立 TCP
1433connection。 demoproject-demodatabase 存在。- Backend application login 可以登入。
- schema migration 和 seed data 成功。
- Backend API 可以正常讀寫 Demo database。
- Backend 重啟後仍然可以重新連線。
- MSSQL container 重啟後,volume 和 database recovery 正常。
- Frontend 使用正確的 Backend URL。
- 沒有任何元件對 Internet 公開 SQL
1433。
這個方案解決什麼、不解決什麼?
| 問題 | 隔離 Demo MSSQL 方案 |
|---|---|
| 需要一個全新的短期測試 database | 可以解決 |
| 不想依賴既有 Azure SQL Private Endpoint | 可以避開這個依賴 |
必須使用既有 demoproject-dev 資料 | 不適用 |
| 需要 Azure SQL Managed Identity authentication | 不會自動保留,通常要改成 SQL login |
| 需要正式資料庫的 HA、backup、SLA | 不適用 |
| Frontend 是否需要 SQL 權限 | 仍然不需要 |
Demo 結束後
這個方案應該被明確記錄為:
temporary isolated demo database
Demo 結束時,依序完成:
- 匯出真正需要保留的 Demo 結果。
- 停止不再使用的 Backend 和 Frontend revision。
- 移除 SQL secrets 和 application credentials。
- 備份或刪除 Demo database volume。
- 刪除 MSSQL Container App。
- 清理 ACR 中不再使用的 Demo image。
- 確認後續部署不會誤連到
demoproject-demo。
總結
在 cae-example-dev-001 自架 MSSQL container,可以讓 Example Company 快速得到一個不依賴既有 Azure SQL 的隔離 Demo database。這個方法適合短期展示和功能驗證,但不是把正式資料庫搬進 Container App,也不是正式 production database 的替代品。
真正需要完成的工作不只是部署一個 MSSQL image,還包括:
- 建立獨立的 MSSQL App。
- 只開放 internal TCP
1433。 - 建立專用 application login。
- 將 Backend connection string 改成新的 Demo database。
- 初始化 schema 和 seed data。
- 決定是否需要持久化 storage 和 backup。
- 將 database bootstrap 與一般 Backend CI/CD 分開。
- 加入 health check、connection retry 和 logs 保護。
- 在 Demo 結束後完整清理資源。
