Docker Compose 經常被認為只適合本機開發,一到生產環境就得換 Kubernetes。這個觀點在 2026 年已經過時了。Compose Specification v5.0(代號 Mont Blanc,2025 年底發布)讓 Compose 的生產可用性大幅提升,對於單機或小規模多服務部署,Compose 仍是最省力、最易維護的選擇。
問題不是工具本身,而是大多數人把開發時的寫法直接搬到線上。
image: latest 只要寫過一次就會後悔
這是最常見、也最致命的錯誤。
1 | # 別這樣做 |
latest 意味著下次 docker compose pull 會拉到不同版本。PostgreSQL 15 跟 16 之間的資料格式不相容,你的服務可能在某個凌晨兩點的自動更新後悄悄死掉。
正確做法是釘定到 minor 版本,並加上 digest 作為額外保險:
1 | image: postgres:16.3-alpine3.20 |
自訂 image 的 tag 應包含語意版本號加上 Git commit hash,這樣出問題時能立即追溯到哪個 commit 引入的。
網路隔離不是可選項
Compose 預設會把所有服務放進同一個 bridge network,表示你的 PostgreSQL 和 Redis 跟對外的 Nginx 容器在同一個網路裡。雖然外部流量進不來,但萬一 Nginx 容器被 RCE,攻擊者可以直接連到資料庫。
正確的做法是明確分層:
1 | services: |
這樣的結構讓 nginx 無法直接連到 db,db 也無法主動對外發起連線。攻擊面縮小到一個服務被入侵只影響同網路的服務,而非整個 stack。
Secrets 管理:千萬別用環境變數傳密碼
environment: POSTGRES_PASSWORD=mypassword 這行字會被存進 docker inspect 的輸出、日誌系統、甚至可能被 CI/CD 工具截到。
最低限度的做法是用 .env 檔搭配 substitution:
1 | # docker-compose.yml |
1 | # .env(不加入版本控制) |
進階做法是使用 Compose 原生的 secrets 機制,密碼會以唯讀檔案掛載到容器的 /run/secrets/ 路徑,不會出現在環境變數:
1 | services: |
.env 跟 secrets/ 目錄都應該加進 .gitignore,並且以 .env.example 和空白的 secret 檔作為範本提交進版本庫。
健康檢查決定服務啟動順序是否可靠
很多人知道 depends_on 但不知道它預設只等容器「啟動」,不等服務「就緒」。資料庫容器啟動但 PostgreSQL 尚未完成初始化時,api 服務就已經開始嘗試連線,然後噴錯。
1 | services: |
start_period 是關鍵:在這段時間內失敗不計入 retries,避免資料庫正常初始化期間被誤判為不健康。
對 Redis 和其他服務也一樣要加 healthcheck,redis-cli ping 就夠了。
Resource Limits 在單機部署尤其重要
沒有設定資源限制的 Compose stack,單一服務的 OOM 會把整台機器的其他服務拖垮。
1 | services: |
limits 是硬上限,超過記憶體會被 OOM killer 殺掉;reservations 是排程用的軟保證,確保容器能拿到最低資源。在資源有限的 VPS 上,這兩個數值都得根據實際用量調整,不能憑感覺亂填。
restart policy 的選擇不是隨便的
1 | restart: unless-stopped |
這是生產環境的建議設定。它在容器 crash 後會自動重啟,機器重開機後也會自動啟動,但如果你手動 docker compose stop 就不會再自動啟。
always 的問題是即使你有意停掉某個服務進行維護,機器重開後它還是會復活,造成困惑。on-failure 則只在非 0 exit code 時重啟,對某些一次性任務容器才適合。
Compose Specification v5 帶來了什麼
最值得注意的是 develop.watch 模式正式成熟,以及 builder 被整合進 Docker Bake,讓 multi-platform builds 的支援更原生。不過對大多數生產部署影響更直接的是:version: 欄位現在明確廢棄,不再需要寫 version: "3.9"。
舊版 docker-compose binary 也已正式退役,統一由 docker compose(中間有空格)替代。如果你的部署腳本還在用 docker-compose up,現在是時候更新了。
另一個實用的新工具是在部署前先跑:
1 | docker compose config |
這個指令會把所有 override 檔案、環境變數替換、預設值全部展開,讓你看到 Docker 實際會執行的完整設定。大多數「Compose 行為怪怪的」問題,在這步就能發現。
備份不在 Compose 裡,但一定要想清楚
Volume 裡的資料不會隨著 docker compose down 消失(除非加 -v),但也不會自動備份。PostgreSQL 資料、上傳的檔案、Redis 持久化資料,這些都需要獨立的備份機制。
最簡單的做法是用 cron 定期 pg_dump,把結果傳到異地儲存。如果是用 SQLite,直接 rsync 整個 .db 檔也行。無論用哪種方式,記得定期測試還原流程,只備份不測試等於沒備份。
如果你正在找一個能穩定跑 Docker Compose 的環境,NCSE Network 的 VPS 搭載 Intel Gold CPU 與 NVMe SSD,位於臺灣是方電訊機房,延遲低、頻寬穩,適合需要長期穩定運行 Docker 服務的開發者與中小企業。詳情可到 ncse.tw 查看方案。