知識與實務

商業實務・AI 應用・人才發展

AI 工作實務

compose.yaml 多服務實作:讓 API 等待 PostgreSQL,驗證資料持久化與故障回復

把 API 和資料庫一起啟動,只完成多服務系統的一半。這份練習用兩個容器驗證三件事:資料庫準備好後才啟動 API、資料庫停止時回傳明確錯誤,以及重建容器後仍讀得到同一筆測試資料。

Compose 中的 Web、API、資料庫及儲存空間

把 API 和資料庫一起啟動,只完成多服務系統的一半。這份練習用兩個容器驗證三件事:資料庫準備好後才啟動 API、資料庫停止時回傳明確錯誤,以及重建容器後仍讀得到同一筆測試資料。

專題編輯:Derek Chou|AI 技術與架構編輯 · 文件核對 2026.11.09

Compose 中的 Web、API、資料庫及儲存空間

已有 Dockerfile,為什麼還需要 Compose?

Dockerfile 描述單一映像如何建置;Compose 把多個服務的映像、網路、啟動條件和資料儲存放在同一份應用設定中。若還不熟悉映像與容器的差異,可先讀Docker 容器部署入門。本文接續處理 API 與 PostgreSQL 的共同啟動、健康狀態及資料生命週期,不重做單容器入門。

假設工程師交付了一個報價服務:api 可正常啟動,卻在第一筆查詢時找不到資料庫;另一位同事重建容器後,測試資料又全部消失。兩個問題分別屬於「依賴是否可用」和「資料存在哪裡」。它們需要不同驗收,不能只用容器清單上的 running 回答。

本練習刻意縮成 API 加 DB,不加入前端、Redis 或訊息佇列。API 只維護一個合成計數器,沒有客戶資料,也沒有登入功能。完成後你會拿到一組能重跑的配置、HTTP 驗證,以及容器重建前後的讀回結果;這些證據適用於練習環境,不代表正式服務已具備備份、容錯或安全防護。

環境、附件與本次驗收範圍

需要可執行 Linux 容器的 Docker Engine/Docker Desktop、Docker Compose v2、Bash 和 Python 3。先執行 docker version 與 docker compose version,確認 Docker daemon 可連線。macOS 的 Docker Desktop 仍是透過 Linux 虛擬機運行這組容器;本文沒有驗證 Windows containers。

下載完整練習檔,解壓後的主要檔案如下:

compose.yaml
api/Dockerfile
api/requirements.txt
api/app.py
verify.sh
README.md

API 使用 Python 3.12 映像與固定的 psycopg[binary]==3.2.9。DB 採 PostgreSQL 18 官方映像。postgres:18 與 python:3.12-slim 是會更新的標籤;練習會記錄實際版本與 DB image digest。若要重建完全相同的供應鏈,還需保存並指定兩個映像的 digest,不能把大版本標籤當成不可變版本。

步驟一:讀懂 compose.yaml 的邊界

檔案中的核心配置如下,完整版本含 API 自身的健康檢查:

services:
  api:
    build: ./api
    ports:
      - "127.0.0.1:${API_PORT:-8000}:8000"
    environment:
      DATABASE_HOST: db
      DATABASE_NAME: appdb
      DATABASE_USER: appuser
    secrets: [db_password]
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:18
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]
    volumes: ["db_data:/var/lib/postgresql"]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
      interval: 3s
      timeout: 3s
      retries: 20
volumes:
  db_data:
secrets:
  db_password:
    file: ./secrets/db_password.txt

Compose 內部以服務名 db 解析資料庫位置;API 裡的 localhost 指向 API 容器本身,不是 DB。DB 沒有宣告 ports,因此本練習不把 PostgreSQL port 發布到主機。API 的主機端綁定 127.0.0.1,目的是讓驗證入口留在本機;這仍不能取代容器隔離、主機防火牆或登入授權。

depends_on 的長格式搭配 service_healthy,讓 Compose 等 DB 健康檢查通過後才建立依賴服務。這個條件處理的是啟動順序;DB 日後中斷,API 仍要自己處理失敗。本例每次請求重新連線,連線失敗時回傳 HTTP 503,沒有宣稱具備自動修復資料庫的能力。Docker 啟動順序文件

PostgreSQL 18 官方映像採用含主版本的資料目錄配置,本例將 named volume 掛到 /var/lib/postgresql。不要把舊版教學的資料路徑直接複製到新映像,也不要用換標籤的方式假裝完成跨大版本資料升級。PostgreSQL 官方映像說明

步驟二:在獨立專案中執行驗證

在解壓後的練習資料夾執行:

bash verify.sh

腳本會產生獨立的 tdr-compose-lab-程序編號 專案名稱,選擇本機空閒 port,建立隨機測試密碼,再執行 docker compose config --quiet 和 docker compose up --build -d --wait。密碼只供本次練習初始化 DB,不列印到輸出,也不應提交到 Git。

Compose secrets 讓服務從 /run/secrets/db_password 讀取檔案;它不是把本機來源檔自動加密。檔案仍須受到主機權限及版本控制排除規則保護,正式環境也需要自己的機密生命週期。Compose secrets 文件

若出現 cannot connect to Docker daemon,應先啟動 Docker;若建置下載失敗,保留網路或 registry 錯誤,再恢復來源。不要以略過建置或移除健康檢查讓流程變綠。驗證腳本只清理自己建立的 Compose 專案,請勿改成指向現有正式專案。

步驟三:驗證可用、故障及資料讀寫

API 提供三個端點:GET /health 實際向 DB 執行查詢;POST /visits 將測試計數加一;GET /visits 讀取當前值。驗證依序檢查健康回應、寫入得到 1、讀回仍為 1。這比只看程序活著更接近應用依賴是否可用。

接著腳本停止 DB,再呼叫 /health。此時預期 HTTP 503,而非成功訊息或無限等待;API 回應只包含通用錯誤,不把資料庫連線細節交給呼叫者。DB 恢復後,下一次請求重新建立連線。這個簡單策略足以教學,但高流量服務仍需設計連線池、有限重試、逾時與監控。

恢復 DB 時,腳本使用下列指令,最多等待 60 秒讓設定中的 DB 健康檢查通過:

docker compose up -d --wait --wait-timeout 60 db

這個寫法在 Compose v2.38.2 的官方文件已列出。該版的 start 沒有 --wait,因此不要直接套用最新文件的所有參數。此練習不改 DB 配置或映像,up 會啟動停止的服務;若配置或映像有變更,則可能重建容器並保留掛載的 volume。應記錄實際 Compose 版本,並以該次完整驗證結果判斷是否成功。v2.38.2 up 文件、v2.38.2 start 文件

真正的結果以 HTTP 狀態與資料讀回為準。看到 DB 容器正在執行,只表示程序存在;看到健康檢查通過,也只涵蓋檢查所測的項目,不代表所有業務流程成功。

步驟四:重建容器,確認資料仍在

腳本先執行不帶 -v 的 docker compose down,再 up -d --wait,最後重新讀取 /visits。預期值仍是 1,表示本次資料跨越容器重建保存在 named volume 中。Compose down 文件

這不是備份還原測試。volume 還在與資料可從異地備份恢復,是兩種證據;主機磁碟損壞、誤刪 volume、資料邏輯毀損,都不會因為用了 named volume 自動解決。要驗證備份,需另外保存資料庫備份、建立空白資料庫、還原並核對關鍵資料,不可把容器重建結果寫成災難復原完成。

腳本結束時會刪除自己建立的測試容器與測試 volume。 這是合成資料的練習清理,不應把同一個 down -v 套用到有價值的資料庫。清理後還會依專案標籤確認容器、網路與 volume 均已移除,並確認合成密碼檔不存在;只有功能驗證與清理皆成功,才輸出 COMPOSE_LAB_PASS。原測試失敗會保留其非零狀態;即使功能成功,清理失敗也以非零結束,細節寫入 evidence/cleanup.log。

交付給下一位工程師前,再看四個差異

容易混為一談的狀態應保留的證據
YAML 可解析與服務可運作config 檢查+實際 HTTP 請求
容器 running 與 DB 可接受查詢健康查詢及錯誤回應
容器重建保留資料與備份可還原前者讀回;後者另做空白環境還原
大版本標籤與精確可重現映像實際 image digest 與依賴版本

本例的資料庫初始化帳號只用於隔離練習,沒有完成正式服務所需的最小權限設計;API 亦未加入認證、TLS、流量限制和監控。把它帶入企業專案時,先替換為專用應用帳號、制定遷移與備份策略,再按實際負載測試。Compose 的價值,是讓服務關係成為可以核對的設定;正式營運責任仍須逐項落實。

常見問題

只有 depends_on: [db] 不行嗎? 它能描述相依啟動順序,卻沒有本例的健康條件。需要等待 DB 就緒時,使用健康檢查及對應條件,並保留應用端錯誤處理。

密碼換了,舊 volume 的 DB 密碼也會跟著換嗎? 不應如此假設。官方映像的初始化變數主要在資料目錄為空時生效;修改已有資料庫的帳密需要正式變更程序。這也是練習使用全新專案與測試 volume 的原因。

可以直接公開這個 API 嗎? 這個端點允許未登入者改變計數,設計目的只限本機驗證。對外服務須另做身分、授權、資源限制與資料規則。

資料來源與素材說明

官方文件核對日:2026 年 11 月 9 至 10 日。程式是本篇原創教學樣本;它驗證特定隔離情境,不宣稱已部署讀者的正式系統。配圖為概念示意,非 Docker 操作截圖;版本、命令與結果以附檔驗證紀錄為準。

內容提供:TARAISG。本文由 AI 協助整理與查核;專題編輯為天地人 AI 編輯計畫的策展角色,未宣稱經具名人工或專家審核。

AI 生成內容

本文由 TARAISG(TIANDIREN AI SOLUTION GROUP)使用 AI 模型產生正文、整理來源並設計實務工具。方法依據與限制列於文末;案例為明確標示的教學假設。未有具名紀錄時,不宣稱經人工或專家審核。

查看內容製作與更正說明

立即領!558元學習投資折抵金

能力投資季。立即領取 558 元學習金!全站線上課立即折抵。只需填寫 Email,即可輕鬆獲得,先領起來,不要錯過!

立即領!559元學習投資折抵金

能力投資季。立即領取 559 元學習金!全站線上課立即折抵。只需填寫 Email,即可輕鬆獲得,先領起來,不要錯過!

立即領!579 元學習金

學習,看見新可能。 10/14 前領取 579 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!599 元學習金

學習,帶來新可能。 09/09 前領取 558 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!558 元學習金

學習,發現新大陸。 8/29 前領取 558 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!559 元學習金

學習,連結新亮點。 8/14 前領取 559 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!555 元學習金

學習,發現更多視角。 6/14 前領取 555 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!556 元學習金

學習,累積無限可能。 5/29 前領取 556 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!557 元學習金

學習,讓我們發現未曾想像的可能!5/14 前領取 557 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!579 元折抵金

知識就是力量,專業成就未來!3/18 前領取 579 元課程折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

年終學習金

年終之餘用學習投資自己!填入 Email ,立即領取 588 元年終學習金!數百堂線上課程立即折抵,先領取收藏起來!