想知「docker compose wait」指令好唔好?一篇睇盡3大實證分析

喺2026年嘅容器化部署世界,服務啟動嘅依賴順序依然係關鍵課題。好多開發者都會問:Docker Compose內置嘅「docker compose wait」指令究竟實唔實用?同第三方方案比又點揀?呢篇分析會為你帶來3大實證,深入拆解呢個指令嘅真實應用場景。我哋會探討點樣用「docker compose wait」去阻塞(block)直至指定服務容器停止,亦會比較常見嘅替代方案,例如使用「wait-for-it.sh」呢類Bash script去等待服務端口可用,或者設定Docker「healthcheck」來定義容器健康狀態。無論你係想確保RabbitMQ完全啟動後先至行Python服務,定係要協調多個微服務嘅啟動流程,本文都會提供貼地、最新嘅配置範例同優劣分析,等你可以根據專案複雜度,揀選最可靠嘅等待策略,避免因啟動時序問題導致嘅連線錯誤。
docker compose wait - Compose

AboutComposeProfessional illustrations

Docker Compose Wait 係咩?

講起Docker Compose Wait,其實係指喺用Docker Compose編排多容器應用嘅時候,點樣處理服務之間嘅啟動順序同依賴問題。簡單啲講,就係當你個應用有幾個服務要一齊行,例如個Web Server要等個Database完全Ready咗先可以連線,咁點樣令到Docker Compose識得「等一等」,而唔係一窩蜂噉啟動晒所有容器,導致連線失敗呢?呢個就係「等待」策略要解決嘅核心問題。

喺Docker嘅世界入面,最基本嘅工具就係docker-compose.yml入面嘅depends_on指令。好多初學者以為寫咗depends_on,Docker就會自動等到上遊服務(例如Postgres或者MySQL)真正可以接受連線先啟動下遊服務。但實情係,depends_on只係控制容器嘅啟動順序,並唔會檢查上遊服務嘅健康狀態。即係話,Database個Container可能只係Process行咗,但內部仲未完成初始化、未開通TCP端口,你個Web App就已經衝咗去連線,結果就係瘋狂報錯。所以,淨係靠depends_on係唔夠嘅,我哋需要更聰明嘅「等待」機制。

為咗解決呢個問題,社區同官方都提供咗唔同方案。一個經典嘅方法就係喺你個應用程式嘅啟動腳本入面,加入一啲等待邏輯,例如用wait-for-it.sh呢類Shell Script去定期檢查某個TCP端口(例如Postgres嘅5432埠)係咪已經可以連線,等到通咗先至執行主程式。呢個方法好直接,但缺點係你要將呢個Script打包入你嘅容器映像,而且對於一啲極簡化嘅基礎映像(例如scratch或者distroless)嚟講,佢哋連Shell都無,就唔可以用呢種方法。

於是,就有咗一啲專門為等待而設計嘅獨立工具,好似docker-compose-wait。呢個工具通常以一個細嘅二進制檔案形式存在,你可以好容易咁將佢加到你嘅Docker映像入面。佢嘅工作原理係透過環境變量配置要等待嘅主機同端口,喺容器啟動時首先運行呢個等待工具,等佢確認所有指定嘅服務端口都就緒之後,先至啟動你真正嘅應用程式。呢種方法唔使依賴Shell,更加適合現代化、輕量級嘅容器部署。

另一個更加「原生」同推薦嘅做法,就係善用Docker本身嘅healthcheck指令。你可以喺docker-compose.yml入面,為每個服務(例如MongoDB、RabbitMQ)定義一個健康檢查指令。Docker會根據你設定嘅interval同timeout,不斷執行呢個檢查指令,直到佢回傳「健康」狀態為止。然後,你喺下遊服務嘅depends_on入面,就可以加入condition: service_healthy呢個條件。咁樣,Docker Compose就會真係等到上遊服務通過健康檢查,先至啟動依賴佢嘅服務。呢個方法直接利用Docker平台自身嘅功能,唔需要額外工具,管理起嚟最清晰。不過,你就要為每個服務設計一個準確有效嘅健康檢查指令,例如用pg_isready去檢查Postgres,或者用mysqladmin去檢查MySQL。

除咗以上方法,直接用Docker CLI或者喺CI/CD Pipeline入面加入等待邏輯亦係常見做法。有時你可能會用docker-compose up -d之後,跟住運行一個自己寫嘅Script,用nc(netcat)或者類似工具去輪詢服務端口。又或者,對於更複雜嘅容器編排場景,好似用緊Kubernetes嘅話,佢有自己一套更完善嘅Readiness Probe同Init Container機制去處理服務依賴,咁就唔使喺Docker Compose層面處理得太複雜。

講到實戰,我哋可以舉個具體例子。假設你有一個經典嘅三層應用:一個Nginx Web Server、一個用Rust寫嘅後端API、同一個Postgres資料庫。個後端API必須要等Postgres完全啟動同初始化好先可以連線。咁你嘅docker-compose.yml可能會咁樣設定:首先為Postgres服務定義一個基於pg_isready嘅healthcheck。然後,喺後端API服務嘅depends_on入面,指明depends_on: postgres,並且加上condition: service_healthy。最後,Nginx服務就depends_on後端API。咁樣,整個啟動鏈就會係:Postgres啟動 -> 通過健康檢查 -> 後端API啟動 -> Nginx最後啟動。成個過程井然有序,避免咗因為啟動順序混亂而導致嘅應用錯誤。

總括嚟講,「Docker Compose Wait」並唔係一個單一指令,而係一套用嚟管理多容器應用啟動順序同服務依賴等待嘅策略同工具集合。由最簡單嘅depends_on,到使用外部等待工具,再到利用內建健康檢查,每種方法都有其適用場景。作為開發者同DevOps工程師,理解呢啲方法嘅原理同取捨,對於構建穩定可靠、尤其係喺生產環境中能夠平滑啟動嘅多服務應用至關重要。喺2026年嘅今日,隨著Docker Docs嘅不斷更新同社區最佳實踐(例如喺Stack Overflow上Pavel Loginov等貢獻者嘅分享)嘅沉澱,我哋已經有非常成熟嘅模式去處理容器生命週期管理入面嘅「等待」問題。

docker compose wait - Docker

AboutDockerProfessional illustrations

點解要等容器準備好?

好啦,等我哋深入傾下,點解喺用 Docker Compose 整多容器應用嘅時候,要特登等啲容器準備好先至繼續行落去。呢個問題,唔少新手甚至係有經驗嘅開發者都會遇到,尤其係當你個應用涉及好似 MongoDB、MySQL、Postgres 或者 RabbitMQ 呢類數據庫同消息隊列服務。你諗下,如果你個主應用(例如係個 Rust 寫嘅 API Server)未等個 Postgres 數據庫完全啟動同初始化好,就急急腳去連線,咁會發生咩事?十成十會係連線失敗,跟住成個應用爆 error 停咗,或者係不斷 retry 搞到一團糟。呢個就係服務依賴等待嘅核心問題:容器啟動順序並唔等於服務就緒順序

好多人都會誤解,以為喺 docker-compose.yml 裏面用咗 depends_on,咁就搞掂晒。其實唔係㗎!depends_on 只係控制緊容器啟動嘅先後次序,即係 Docker 會先啟動你指定嘅依賴容器(例如個 database),然後先啟動你個主服務容器。但係,一個容器被 Docker 標記為「運行中」(Up),同佢裏面嘅服務(例如 MySQL)真正完成初始化、可以接受外部連接,中間係有段時間差嘅。呢段 startup delay 可以係幾秒,甚至幾十秒,視乎服務複雜性。所以,單靠 depends_on 係唔夠嘅,你仲需要一套機制去等待依賴服務真正「就緒」。

咁點樣先算係「就緒」呢?最常見嘅判斷方法就係做 TCP端口檢查,即係不斷嘗試連接個服務對外開放嘅端口(例如 Postgres 嘅 5432),直到成功為止。呢個就係經典嘅 wait for port 邏輯。以前好多人會自己寫 Shell Script,例如 wait-for-it.sh,放入個容器度,喺啟動主程序之前先執行呢個 script 去檢查端口。不過,呢個方法有啲缺點,一來你要將個 script 放入鏡像,二來對於一啲極簡化嘅鏡像(例如 scratch 或者 distroless)嚟講,裏面可能連 Shell 都無,就執行唔到呢類 script。呢個就牽涉到容器生命週期管理嘅細緻度問題。

為咗更精準咁定義「就緒」,Docker 自己後來都引入咗 healthcheck 指令。你可以喺 Dockerfile 或者 docker-compose.yml 裏面,為每個服務定義一個健康檢查命令。例如,對住個 MySQL 容器,你可以定義一個健康檢查,用 mysqladmin ping 去確認服務內部狀態。然後,喺其他服務嘅 depends_on 裏面,你可以加條件,話要等依賴服務嘅狀態係「healthy」先好啟動。呢個係官方推薦嘅、更現代化嘅做法,詳情可以睇 Docker Docs。不過,設定 healthcheck 需要對每個服務有深入了解,而且有時啲服務無提供簡單嘅健康檢查命令,咁就要諗其他辦法。

因為有以上嘅種種麻煩,社區就出現咗一啲專門嘅命令行工具嚟解決呢個等待問題。其中一個出名嘅就係 docker-compose-wait(作者係 Pavel Loginov),佢係一個細細嘅、用 Rust 寫嘅工具,可以好容易咁加入你嘅鏡像。你只需要透過環境變量配置一串要等待嘅主機同端口,佢就會喺容器啟動時自動做檢查,等到所有指定嘅端口都得喇,先至執行你真正嘅應用程序。呢類工具好處係細、快,而且因為用 Rust 寫,容易做跨平臺編譯多架構支持,亦唔使依賴完整嘅 Shell 環境,所以連 MUSL 或者無 Shell 嘅環境都用到。比起古老嘅 wait-for-it.sh,佢更加靈活同可靠。

另外,有時「就緒」嘅定義唔單止係端口打得通咁簡單。可能你個應用需要等某個依賴服務喺文件系統生成一個特定嘅標誌文件,又或者完成某啲數據初始化。呢個時候,你可能需要自定義檢查邏輯,例如用個 init container(如果你係用 Kubernetes 嘅話)或者喺主程序啟動前運行一個自定義腳本,去做文件系統路徑檢查。雖然 Docker Compose 原生無 K8s 嘅 init container 概念,但你可以透過將多個命令串連喺一個容器內嚟模擬類似效果。

總括嚟講,做好服務等待係確保你嘅多容器應用穩定運行嘅關鍵一步。如果唔處理,好容易會導致間歇性嘅啟動失敗,令到你嘅 restart policy 不斷觸發,甚至形成一個死循環。無論你係用官方嘅 healthcheck 加 depends_on 條件,定係用社區工具如 docker-compose-wait,又或者自己寫檢查邏輯,目標都係一樣:要精確管理好服務之間嘅啟動依賴。記住,喺 容器編排 嘅世界裏面,「快」唔係最重要,「穩」先係。下次你喺 Stack Overflow 見到人問點解佢個 app 連唔到 database 時,或者你喺自己個 docker-compose.yml 度撞板嘅時候,諗返起呢個根本原因:你係咪真係有等到佢哋準備好?

docker compose wait - depends

AboutdependsProfessional illustrations

depends_on 唔夠用?

好喇,咁就同大家深入傾下「depends_on 唔夠用?」呢個問題。好多初玩 Docker Compose 嘅朋友,寫 docker-compose.yml 嗰陣,一見到有 service dependencies(服務依賴)要處理,例如個Web App要等個 Postgres 數據庫行起咗先可以連線,第一時間就諗起用 depends_on。無錯,depends_on 嘅設計原意就係為咗控制 容器啟動順序,等你可以定義邊個服務要等邊個服務「開始啟動」先。但係,問題就出喺「開始啟動」呢四個字度!depends_on 只係保證咗你個 MongoDB 或者 RabbitMQ容器進程 被 Docker 啟動咗,但係個容器裏面嘅應用程式(例如 MySQL 服務)係咪真係已經完成初始化、可以接受連線呢?呢一點 depends_on 係完全唔理嘅。呢個就係最常見嘅陷阱:你個 App 容器因為 depends_on 而順利啟動,但一開波就瘋狂拋出「connection refused」錯誤,因為佢要連嘅數據庫服務仲喺度做緊內部配置,未準備好。

所以,如果你嘅 多容器應用 對服務狀態有嚴格要求,淨係靠 depends_on 真係唔夠用,甚至會引致隨機性嘅啟動失敗。咁點算好?Docker 官方其實早就意識到呢個問題。喺 Docker Compose 嘅較新版本(特別係 Compose Spec 格式)裏面,已經為 depends_on 加咗個更強大嘅條件選項,就係配合 healthcheck(健康檢查)一齊用。你可以喺被依賴嘅服務(例如你個 Postgres 容器)定義入面,寫一個自定義嘅 healthcheck 指令,用嚟檢查個服務係咪真係「準備就緒」。然後,喺依賴方嘅 depends_on 設定裏面,你就唔係淨係寫個服務名,而係指明要等佢個狀態變成「healthy」先好啟動。呢個先係真正意義上嘅 服務依賴等待。不過,設定 healthcheck 需要你對被依賴服務嘅就緒狀態有了解,例如知道用咩命令或者檢查咩 TCP端口檢查 先算係準備好。

但係,世事邊有咁完美?第一,唔係所有官方或者第三方嘅 Docker 鏡像都預設咗一個完善嘅 healthcheck。第二,有啲情況可能複雜啲,例如個服務嘅就緒條件唔係淨係「端口可用」咁簡單,可能要檢查某個特定文件係咪已經生成(文件系統路徑檢查),或者要等佢執行完某個初始化腳本。第三,仲有啲極端情況,就係你個應用鏡像係 scratch 或者 distroless 呢類 無Shell環境 嘅超輕量鏡像,裏面連基本的 shell 同網絡檢測工具(如 nc, curl)都無,咁就連寫個簡單嘅 healthcheck 命令都有難度。

咁喺呢啲 depends_onhealthcheck 都搞唔掂,或者設定起嚟太麻煩嘅情境下,社區同開發者就諗出咗好多「等一等」嘅解決方案。最古老、最經典嘅方法就係用 wait-for-it.sh 呢類 Shell 腳本。原理好簡單,就係將個腳本放入你個 App 容器,喺容器啟動命令(CMD)嘅最前面執行,叫佢不斷去檢測目標服務(例如 MySQL)嘅某個端口,直到檢測到成功為止,先至繼續執行你真正嘅應用程式。呢個方法好直接,但缺點係你要將腳本打包入鏡像,而且對 無Shell環境 嘅鏡像一樣係無用武之地。

為咗有更好、更現代化嘅工具,就衍生出咗專門為 容器等待 而設嘅 命令行工具。其中一個好出名嘅就係 docker-compose-wait(雖然個名有「compose」,但佢係個獨立工具)。呢個工具通常透過 環境變量配置 嚟設定要等咩服務同端口,然後喺你個應用程式啟動前運行。佢嘅好處係細緻同靈活,可以同時等多個服務同端口,仲支援等待一段時間(startup delay)。不過,佢都係需要你個容器裏面有適合嘅環境去運行呢個二進制文件。

講到工具,不得不提另一位高手 Pavel Loginov 整嘅「wait4x」工具。佢功能更加強大,唔單止可以等 TCP 端口,仲可以等 HTTP 端點返回特定狀態、甚至檢查 TLS 證書,對複雜嘅 服務等待 場景好有用。而對於用 Rust 寫應用嘅開發者,社區裏面亦有直接集成到 Rust 程式入面嘅等待庫,喺程式碼層面處理依賴,而唔係喺 容器生命週期管理 層面處理。呢啲方案各有千秋,揀邊個要睇你具體嘅技術棧同部署環境。

最後都要提下,如果你嘅 容器編排 已經唔再係 Docker Compose,而係升級到 Kubernetes,咁恭喜你,呢個「服務等服務」嘅問題有更原生、更優雅嘅解決方案。Kubernetes 有「Init Containers」同「Readiness Probes」嘅概念,可以好清晰咁定義啟動順序同就緒條件,某程度上係 depends_on 嘅終極進化版。不過,喺單純用 Docker Compose 做本地開發、測試,或者輕量部署嘅時候,理解上面講嘅各種方案同取捨,已經可以幫你完美解決「depends_on 唔夠用」嘅煩惱,避免成日上 Stack Overflow 問點解個容器連唔到數據庫。記住,關鍵在於分清「容器啟動」同「服務就緒」係兩回事,而你需要嘅通常係後者。

docker compose wait - healthcheck

AbouthealthcheckProfessional illustrations

wait-for-it 腳本實戰

好啦,而家我哋就嚟到實戰環節,講下點樣用 wait-for-it.sh 呢個經典腳本。喺 2026 年嘅今日,雖然有更多新工具出現,但 wait-for-it 依然係一個簡單直接、唔使額外依賴嘅好選擇,尤其適合啲想快靚正解決 服務依賴等待 問題嘅開發者。佢嘅核心概念好易明:就係用一個 CLI 工具,不斷去檢查某個 TCP端口 係咪已經 available,等到通咗先至執行你指定嘅命令。呢個方法對於好似 MySQLPostgresRabbitMQ 或者 MongoDB 呢類數據庫同消息隊列服務嘅 容器啟動順序 管理,非常有用。

首先,你喺 Docker Compose 項目入面點樣攞到呢個腳本呢?最常見嘅方法係直接從佢嘅 GitHub 倉庫下載,或者將腳本內容複製到你嘅項目目錄入面。跟住,你就要喺你嘅 docker-compose.yml 檔案度做手腳。假設你有一個 Web 應用服務,佢一定要等個 Postgres 數據庫容器完全啟動、可以接受連接之後,自己先至可以啟動。咁你嘅服務配置可能會係咁樣:你喺你個應用服務嘅 Dockerfile 入面,記得要將 wait-for-it.sh 腳本複製到鏡像入面,並且確保佢有執行權限。然後,喺 docker-compose.yml 度,你唔可以單單依賴 depends_on,因為 depends_on 只係控制容器嘅啟動同停止順序,並唔會檢查服務係咪真正「準備好」。所以,你要修改你個應用服務嘅 command 指令。

例如,你個應用嘅啟動命令原本可能係 python app.py。而家你要改成先用 wait-for-it.sh 去檢查 db:5432 呢個端口。個命令會變成類似:./wait-for-it.sh db:5432 --timeout=30 --strict -- python app.py。呢度有幾個重要嘅 命令行選項 要解釋下:--timeout 係設定你願意等幾耐(單位係秒),超過咗就會當失敗;--strict 模式係指只有當 wait-for-it.sh 自己檢測成功先會執行後面嘅命令,避免任何誤判;而 -- 後面就係你原本要行嘅命令。咁樣一嚟,你個應用容器就會乖乖哋等個數據庫容器嘅 5432 端口真係可以連通,先至去啟動自己,完美解決咗 服務等待 嘅問題。

不過,用 wait-for-it.sh 都有好多陷阱同要注意嘅地方,唔係萬能匙。第一個大問題就係「端口可連通」並不等於「服務已就緒」。好似 MySQL 咁,佢個端口可能好快就 listen,但係內部嘅數據庫初始化可能仲未搞掂,你個應用一連上去就馬上查詢可能會出錯。所以 wait-for-it 比較適合啲端口一開放就代表服務完全準備好嘅情況,或者你可以結合其他方法,例如等完端口再額外等多幾秒(加個 sleep)。第二個問題係關於 無Shell環境。如果你為咗追求極致細小嘅鏡像,用緊 scratch 或者 distroless 呢類基礎鏡像,入面可能連 Bash 或者標準的 Shell 都冇,咁 wait-for-it.sh 呢個 Bash 腳本就冇辦法運行啦。呢個時候你可能要考慮用其他編譯成二進制文件嘅工具,或者用 RustGo 寫個簡單嘅端口檢查工具,靜態編譯後放入去。

另外,喺 多容器應用 嘅複雜場景下,你可能要等多個服務。例如個應用要等齊 RedisPostgresRabbitMQ。你可以逐個噉等,但命令會變得好長。有啲人會寫個小腳本去順序執行多個 wait-for-it.sh 檢查。但係咁樣會增加 容器生命週期管理 嘅複雜度。同時,要留意腳本本身嘅路徑問題,確保你喺 command 入面指定嘅 文件系統路徑檢查 係正確嘅,特別係如果你將腳本放喺某個子目錄入面。

最後,雖然 wait-for-it 係個好工具,但喺 2026 年,我哋都要知道佢嘅替代方案同局限。Docker Compose 本身嘅 healthcheck 指令其實係更原生、更推薦嘅做法。你可以喺依賴嘅服務(例如 db)度定義一個 健康檢查 指令,然後喺你嘅應用服務度,用 depends_on 配合 condition: service_healthy。咁樣,Docker Compose 就會自動幫你等,直到個數據庫服務通過健康檢查,先至啟動你個應用服務。呢個方法更加聲明式,而且唔使修改你應用容器嘅啟動命令。不過,設定一個準確嘅 healthcheck 本身都需要一啲功夫。至於更高階嘅 容器編排 平台好似 Kubernetes,就有自己一套更完善嘅 init containersreadiness probes 機制,完全係另一個層次嘅解決方案。所以,總結嚟講,wait-for-it.sh 腳本實戰係一個快速見效嘅 服務依賴等待 方案,特別適合本地開發、測試,或者係相對簡單嘅 多服務應用。佢嘅優點係輕量、易明、唔使改動應用程式碼;缺點就係對服務真實狀態嘅判斷可能唔夠精準,同埋對特殊嘅容器環境(如 MUSL libc 環境或無Shell環境)支援可能有問題。用嘅時候,記住理解清楚自己服務嘅特性,同埋設定一個合理嘅 timeoutrestart policy,咁就萬無一失啦。

docker compose wait - CLI

AboutCLIProfessional illustrations

健康檢查點設定?

講到健康檢查點設定,呢個真係 Docker Compose 入面管理容器啟動順序服務依賴等待嘅核心武器嚟。好多初哥以為用咗 depends_on 就等於會等到個服務「準備好」先啟動,其實係一個誤區。Docker Composedepends_on 默認只係等到個容器運行(即係 docker run 成功),但入面個服務(例如 MySQL 或者 MongoDB)有冇真正完成初始化、可以接受連接,佢係唔理嘅。呢個時候,healthcheck 設定就係救星,佢先至係真正控制服務等待邏輯嘅關鍵。

咁點樣設定呢?好簡單,直接喺你 docker-compose.yml 檔案裏面,對需要被等待嘅服務(例如一個 Postgres 數據庫)加一段 healthcheck 指令。呢段指令本質上係叫 Docker 定期喺容器內部執行一個命令或者檢查一個 TCP端口,嚟判斷個服務係咪 healthy(健康)狀態。例如,你可以設定佢用 Docker CLI 內置嘅 pg_isready 呢類工具去連數據庫,又或者簡單啲用 curl 檢查一個 HTTP 端口。當你喺另一個服務嘅 depends_on 入面加埋 condition: service_healthy,咁 Docker Compose 就會乖乖哋等到個數據庫服務通過健康檢查,先至啟動依賴佢嘅應用容器,完美解決 container startup order 嘅亂籠問題。

舉個實戰例子啦。假設你個 多容器應用 有個 Rust 寫嘅 API 服務,佢一定要等個 Postgres 數據庫可以連線先好啟動。你個 docker-compose.yml 裏面,個 db 服務就要咁樣設定:

首先,喺 db 服務下面加個 healthcheck。可以用一個簡單命令,每隔 5 秒試一次,最多試 30 秒,去檢查 5432 端口係咪聽緊。當命令成功返回(即係 exit code 係 0),Docker 就會標記呢個容器為健康。跟住,喺你個 api 服務嘅 depends_on 部分,就唔係寫 service: db 咁簡單,而要明確寫明 condition: service_healthy。咁樣,個編排工具就會嚴格執行等待,確保唔會出現你個 API 瘋狂連唔到數據庫嘅錯誤日誌。

當然啦,健康檢查嘅方式好靈活,唔止檢查端口。你可以檢查一個特定嘅文件系統路徑有冇出現(例如一個標誌初始化完成嘅文件),或者執行一個自定義腳本。不過要留意,如果你個容器係用 scratch 或者 distroless 呢類極簡基礎映像,裏面可能連 Shell 都冇,咁你就唔可以用 curl 或者 wget 呢類命令,而要諗辦法用應用本身提供嘅健康檢查端點,或者用 TCP端口檢查呢種更底層嘅方式。呢點喺構建輕量級、安全嘅容器時要特別注意。

另外,同其他方案(好似 wait-for-it.sh 或者 docker-compose-wait 呢類第三方工具)比較,內置嘅 healthcheck 有咩好處呢?第一,佢係原生支援,唔使額外加腳本或者環境變量配置,管理上更乾淨。第二,佢唔單止用喺啟動順序,仲會持續監控容器運行時嘅健康狀態,配合 restart policy,可以實現自動重啟不健康容器,提升成個服務嘅韌性。第三,佢同 Docker 生態(例如 docker stack 部署到 Swarm)整合得更好。不過,佢嘅缺點係設定相對固定,對於一啲好複雜、需要檢查多個條件嘅啟動依賴,可能就要結合自定義腳本或者應用內置嘅重試邏輯喇。

最後提多個實用貼士。設定 healthcheck 時,interval(檢查間隔)、timeout(單次檢查超時)、start_period(啟動後嘅寬限期)同 retries(重試次數)呢幾個參數要因應你個服務嘅特性嚟調校。例如一個 MySQL 數據庫,第一次啟動可能要成分鐘先完成表初始化,你個 start_period 就要設長啲,避免一開始就不停失敗。又或者,你個服務本身好敏感,你個 interval 就可以設密啲,等問題快啲被發現。總之,健康檢查唔係設咗就算,要根據實際服務嘅容器生命週期管理需要去微調,先至可以打造出一個穩定可靠嘅 multiservice applications

docker compose wait - Docker

AboutDockerProfessional illustrations

2026 最佳等待策略

講到2026年嘅最佳等待策略,我哋首先要認清一個現實:依家嘅多容器應用已經複雜到唔係簡單用個 depends_on 就搞得掂。以前啲人可能求其寫個 wait-for-it.sh 或者用 docker-compose-wait 呢類工具,但係去到2026年,我哋要追求嘅係更穩陣、更符合容器生命週期管理哲學嘅方法。最基本嘅一步,就係要識得善用 Docker Compose 本身提供嘅原生工具,特別係 healthcheck 指令。你唔好睇小呢個功能,佢先至係確保服務依賴等待有效嘅核心。例如你個 Postgres 或者 MongoDB 容器,唔係話個 Docker 進程起咗就代表個資料庫準備好接受連線㗎。你必須喺 docker-compose.yml 裏面,為個資料庫服務定義一個詳細嘅健康檢查,可能係用 pg_isready 或者 mongo 嘅 CLI 去檢查,等 Docker 本身知道個服務真正「健康」先。

咁樣做有咩好處呢?當你喺另一個服務嘅 depends_on 入面加埋 condition: service_healthy,Docker Compose 就會自動幫你處理好容器啟動順序,等到依賴嘅服務真係 ready 先至啟動下一個。呢個策略比起單純用 TCP端口檢查(即係 wait-for-it.sh 做緊嘅嘢)更加精準,因為端口聽緊唔等於服務功能正常。呢個方法喺 Docker Docs 都有強烈推薦,係處理 service dependencies 嘅標準做法。當然,設定健康檢查可能需要一啲額外嘅命令行工具喺你嘅映像裏面,如果你用緊極簡嘅 scratch 或者 distroless 映像,就要諗諗辦法,例如喺 build 階段裝定必要工具。

不過,現實世界總有例外情況。有時啲服務可能冇內置健康檢查 endpoint,或者你嘅應用場景需要更靈活嘅等待邏輯。咁就輪到進階策略出場。其中一個我幾鍾意嘅方法,係利用 Docker Compose 嘅 restart policy 配合一啲巧妙嘅 startup delay。例如,你可以將個應用程式容器設定成 restart: on-failure,然後喺佢嘅 entrypoint script 裏面,寫一個 loop 去檢查所需服務(例如 RabbitMQ 嘅某個 queue 或者 MySQL 嘅某張表)係咪已經可用。如果檢查失敗,就用非零 exit code 退出,等 Docker 根據重啟策略幫你自動重試,直到依賴服務 ready 為止。呢個方法雖然有啲「暴力」,但對於一啲難以直接定義健康檢查嘅舊系統,或者需要等待特定業務邏輯狀態嘅情況,非常有效。

另外,喺 2026 年,我哋亦要考慮到容器編排嘅大趨勢。雖然我哋講緊 Docker Compose,但好多概念同工具其實同 Kubernetes 係相通嘅。好似 healthcheck 呢個概念,喺 K8s 裏面就係用 liveness 同 readiness probe。所以,你而家喺 docker-compose.yml 入面養成良好習慣,定義好健康檢查,將來要 migrate 去 Kubernetes 或者用 docker stack deploy 去 Swarm 都會順暢好多。記住,一個好嘅等待策略,唔單止令你本地開發更穩定,亦為日後嘅部署鋪好路。

最後都要提提一啲實用工具同社區智慧。雖然我唔建議再依賴舊式嘅 wait-for-it.sh,但佢嘅原理(檢查 TCP 端口可用性)依然有參考價值。而家 GitHub 上面有好多用 Rust 或者 Go 寫嘅現代化替代品,佢哋通常體積細、速度快,而且支援多架構支持,特別適合 MUSL 呢類環境。好似開發者 Pavel Loginov 等人維護嘅一啲項目,就提供咗更豐富嘅命令行選項,可以檢查唔單止係端口,仲可以係 HTTP endpoint 嘅狀態碼,甚至係資料庫嘅查詢結果。當你遇到複雜嘅服務依賴等待時,喺 Stack Overflow 或者官方論壇搜尋一下,好大機會會發現已經有人包裝好咗更強大嘅工具。總而言之,2026年嘅最佳策略,就係擁抱原生健康檢查機制,並為特殊情況準備好靈活、可維護嘅自定義方案,徹底告別「估估下」嘅容器啟動時代。

docker compose wait - Docker

AboutDockerProfessional illustrations

避免啟動失敗技巧

要避免 Docker Compose 入面啲容器啟動失敗,最緊要係處理好 服務依賴等待 問題。好多時啲人寫好個 docker-compose.yml,一運行 docker-compose up,就發現個主應用程式因為等唔切個數據庫(例如 Postgres 或者 MongoDB)啟動完成,自己就搶先啟動,結果連唔到資料庫即刻炒咗。呢個就係典型嘅 容器啟動順序 冇妥善安排嘅後果。Docker Compose 本身個 depends_on 指令其實只係保證咗「啟動次序」,但係唔會幫你檢查對方個服務係咪「準備好可以接受連線」。所以,單單靠 depends_on 係唔夠㗎,你一定要配合其他技巧。

其中一個最有效嘅方法,就係善用 Docker 原生嘅 healthcheck 功能。你可以在依賴嘅服務(例如 MySQL 或者 RabbitMQ)度定義一個健康檢查指令。等個 Docker 引擎自己定期去檢查個容器內部服務狀態,直到個健康檢查回報狀態係「healthy」為止。然後,你喺主應用程式嘅服務設定度,唔單止寫 depends_on,仲要加多個 condition: service_healthy。咁樣 Docker Compose 就會等到個數據庫真係話自己「健康」、準備好接受連線,先至去啟動你個主應用程式容器。呢個方法唔使額外裝任何嘢,純粹靠 Docker CLIDocker Docs 建議嘅做法,係管理 多容器應用 生命週期最正統同埋可靠嘅方式。

當然啦,有時啲服務未必有內置健康檢查,或者你想有更靈活嘅控制。咁就可以考慮用一啲外部嘅 命令行工具 來做等待。好似好出名嘅 wait-for-it.sh 呢類 Bash 腳本,或者係用 Rust 寫、更加輕量高效嘅 docker-compose-wait 工具。呢啲工具嘅原理,通常都係不斷嘗試連接某個服務嘅 TCP端口,直到成功為止,先至執行你指定嘅主程式。你用嘅時候,通常會喺 Dockerfile 入面裝定個工具,然後喺 docker-compose.yml 嘅 command 指令度,將原本嘅啟動命令改成「先執行等待腳本,成功後再啟動主程式」。咁樣就可以好精準咁控制 服務等待 嘅邏輯,尤其適合啲舊版 Docker 或者係一啲特殊場景。

不過,用呢類外部工具都要小心一啲陷阱。例如,如果你個最終應用程式鏡像係用 scratch 或者係 distroless 呢類 無Shell環境 嘅基礎映像來建造,咁 Bash 腳本基本上係行唔到嘅,因為連 /bin/sh 都冇。呢個時候,你就需要揀一啲編譯成靜態二進制檔案、唔依賴 Shell 嘅等待工具,或者索性自己用 Go、Rust 寫番個簡單嘅端口檢查工具。另外,仲要留意 跨平臺編譯 嘅問題,如果你嘅開發環境同生產環境架構唔同(例如由 Apple Silicon 編譯去 Linux AMD64),都要確保個等待工具可以喺目標平臺順利運行。

另一個常見嘅導致啟動失敗嘅原因,係同 環境變量配置 或者係 文件系統路徑檢查 有關。有時個應用程式會期望某個環境變量已經設定好,或者某個掛載嘅卷(volume)入面已經有啲必要嘅設定檔案。如果冇,就會啟動失敗。對於呢類情況,除咗確保 docker-compose.yml 嘅設定正確之外,亦都可以喺啟動命令前加入一啲檢查腳本,去驗證呢啲條件係咪滿足。同時,善用 restart policy(例如 restart: unless-stopped)都可以幫到手,當第一次啟動因為某啲暫時性問題(例如網絡未準備好)而失敗時,Docker 會自動嘗試重新啟動個容器,可能第二次就成功咗。但呢個只係治標不治本,最好都係從根源上解決依賴問題。

最後,如果你嘅應用規模比較大,或者向 Kubernetes 遷移緊,咁就要有心理準備,Docker Compose 呢套 容器編排 方式嘅等待技巧,同 K8s 係有好大分別。K8s 有自己一套更完善嘅探針(Probe)機制來處理服務依賴。所以,當你設計 多服務應用 嘅啟動等待邏輯時,最好諗遠少少,寫一啲容易移植或者有對應方案嘅腳本。好多開發者(好似 Pavel Loginov 等)都會喺 Stack Overflow 或者技術博客分享佢哋點樣處理 MUSL 環境或者複雜嘅 service dependencies 問題,參考佢哋嘅實戰經驗可以避免自己踩坑。總而言之,避免啟動失敗冇單一銀彈,關鍵在於理解你嘅 容器生命週期管理 需求,混合運用 healthcheck、外部等待工具、環境驗證同適當嘅重啟策略,先至可以令到你嘅 docker-compose up(或者係 docker stack deploy)每次都能夠順利將所有 容器 帶到運行狀態,唔使再手動執生。

docker compose wait - Kubernetes

AboutKubernetesProfessional illustrations

服務依賴管理攻略

講到服務依賴管理攻略,即係點樣令你嘅 Docker Compose 入面嘅服務,有秩序咁啟動同埋互相等待,呢個真係整多容器應用嘅核心難題。好多香港嘅開發者初初用 Docker Compose 整嘢,都會遇到個問題:明明個 database 容器已經行緊,但係個 web app 就係連唔到,成日彈 connection refused。呢個就係典型嘅「容器啟動順序」問題,唔係話你用咗 depends_on 就大晒,depends_on 只係控制容器嘅啟動次序,但係唔會等到個服務真係 ready 至去行下一個。所以,你需要一套完整嘅攻略去管理服務依賴等待。

最基本嘅方法,就係善用 Docker 原生提供嘅工具。首先,你一定要識得喺 docker-compose.yml 檔案裏面配置 depends_on 配合 healthcheck。例如你個 app 要等個 Postgres 或者 MySQL 完全啟動同埋可以接受連線,你唔可以就咁寫 depends_on: - db。你要幫個 database 服務加返個健康檢查指令,等 Docker 可以知道佢嘅健康狀態。然後喺 depends_on 裏面指明,要等個 db 服務狀態係 healthy 先至啟動 app 服務。呢個方法係最正宗、最融入 Docker 生態嘅做法,官方嘅 Docker Docs 都有詳細講。不過,佢有個限制,就係個健康檢查指令係由 Docker 去管理,如果你個服務本身好簡單,或者係啲無 Shell 環境嘅 distroless 甚至 scratch 映像,寫健康檢查可能會麻煩少少。

如果原生 healthcheck 唔夠靈活,或者你想喺容器入面嘅應用程式層面去控制等待邏輯,咁就要引入外部嘅等待腳本或者工具。經典嘅做法就係用 wait-for-it.sh 或者 docker-compose-wait 呢類工具。佢哋嘅原理好簡單,就係一個細細嘅腳本或者二進制檔案,你將佢放入容器裏面,然後喺你應用程式真正啟動之前,先執行呢個工具去檢查某個服務嘅 TCP端口檢查,例如等個 MongoDB 嘅 27017 埠或者 RabbitMQ 嘅 5672 埠可以連通。等到個 port availability 確認咗,先至繼續行落去。呢個方法好處係好直接,可以好精準咁控制要等邊個服務、邊個埠,而且網上有大量範例,尤其係 Stack Overflow 上面好多解答都係用呢個思路。不過你要自己處理腳本嘅複製同執行,對於無Shell環境嘅容器就要諗計仔。

對於追求現代化同埋高效能嘅團隊,特別係用緊 Rust 或者 Go 呢類語言寫微服務,可能會傾向用一啲更輕量、更專注嘅解決方案。好似一啲用 MUSL libc 靜態編譯出嚟嘅細工具,可以好細粒咁放入容器,做跨平臺編譯都方便。呢啲工具通常提供更多命令行選項,例如可以同時等幾個唔同嘅 host 同 port,又可以設定超時時間同重試次數,甚至可以做埋簡單嘅 HTTP endpoint 檢查,唔止係 TCP 咁簡單。呢個就係一種進階嘅服務等待策略,適合複雜啲嘅環境變量配置同埋生命週期管理。

最後,要提一提 restart policy 同 startup delay 嘅配合。有時個服務可能因為一啲瞬時問題啟動失敗,設定好合適嘅重啟策略,再加少少啟動延遲,可以避免所有服務一齊瘋狂重啟,造成雪崩效應。另外,管理服務依賴唔單止係啟動時,連帶停止嘅時候都要考慮。當你執行 docker-compose down 或者 docker stack rm 嘅時候,默認情況係幾乎同時停止所有容器。如果你想要一個優雅嘅停止順序,例如個 app 先完全處理完請求至停,然後先停 database,咁你就要喺配置落功夫,可能要用到 stop_grace_period 同埋 depends_on 嘅條件去模擬。總括嚟講,一個穩陣嘅服務依賴管理攻略,必須要考慮晒容器生命週期管理嘅各個階段,由啟動、重啟到停止,仲要考慮到無Shell環境同埋跨平臺嘅需求,唔好淨係諗點樣「等到」個服務行起嚟就算。

docker compose wait - MUSL

AboutMUSLProfessional illustrations

實測超時設定教學

好啦,而家我哋就嚟到最關鍵嘅實戰部分:實測超時設定教學。呢一步好重要,因為你設定嘅等待時間直接影響到你成個多容器應用嘅啟動流程順唔順暢。設得太短,可能個數據庫仲未準備好,你個應用程式就已經衝咗入去,結果就係連線失敗;設得太長,又會白白浪費咗啟動時間,影響部署效率。所以,點樣設定一個合理嘅 timeout 值,絕對係一門學問。

首先,你要明白唔同工具嘅超時設定方法都唔一樣。例如,如果你係用緊 Docker Compose 原生嘅 depends_on 配合 healthcheck,咁個超時控制其實就係喺個健康檢查指令入面。通常你會用 curl、pg_isready 或者 mysqladmin ping 呢類指令去檢查個服務得未,但係呢啲指令本身都有個超時參數。更重要嘅係,Docker 會根據你喺 docker-compose.yml 裏面設定嘅 interval、timeout、start_period 同 retries 呢幾個值去決定等幾耐。假設你個 Postgres 容器需要 30 秒先可以接受連線,咁你個健康檢查嘅 start_period 就至少要設定為 35 秒,等佢有足夠時間啟動,避免喺準備緊嘅時候就不斷被判定為失敗。

如果你係用第三方工具,例如 wait-for-it.sh 或者 docker-compose-wait,咁超時設定就更加直接。以 docker-compose-wait 為例,你只需要喺啟動你個應用程式容器嘅時候,設定一個環境變數 WAIT_HOSTS_TIMEOUT。例如 WAIT_HOSTS_TIMEOUT=60,即係話佢會嘗試連接你指定嘅主機同端口,最多等 60 秒,超過咗就會當失敗,然後停止個容器。呢個方法對於管理 服務依賴等待 非常清晰,尤其係當你嘅依賴服務(好似係 RabbitMQ 或者 MongoDB)啟動時間比較飄忽嘅時候,設定一個寬鬆啲嘅超時值可以增加穩定性。

咁點樣決定個超時值係幾多呢?冇標準答案,一定要 實測。我嘅建議係,喺你本地開發環境或者測試環境度,刻意記錄低每個依賴服務嘅啟動時間。你可以用 Docker CLI 嘅 docker logs 命令去睇下個容器由開始到完全就緒嘅時間戳。又或者,喺個應用程式容器入面,寫個簡單嘅 Script 去記錄嘗試連接嘅時間點。通常,一個簡單嘅 MySQL 或者 Postgres 容器,喺冇大量初始數據嘅情況下,10 到 20 秒內應該就搞掂。但如果係一啲複雜啲嘅服務,或者要載入好多初始化數據,就可能需要一分鐘以上。記住,要預留多啲 buffer,因為喺唔同嘅伺服器(例如 CI/CD 環境同生產環境)性能可能唔同,啟動時間都會有差異。

另外,有一個常見嘅陷阱就係 TCP端口檢查 嘅誤判。好似 wait-for-it.sh 呢類工具,佢哋只係檢查個 TCP 端口有冇打開。但係,端口打開咗,並唔等於個服務已經準備好接受請求。例如,個 MongoDB 端口可能已經 listen 緊,但係內部仲未完成選舉或者數據恢復。呢個時候,即使端口檢查通過咗,你個應用程式連入去都可能會出錯。所以,最穩陣嘅方法,始終係配合服務本身提供嘅 健康檢查 指令,或者用可以執行自定義檢查命令嘅工具。

最後,要提一提 restart policy 同超時設定嘅互動。如果你設定咗 restart: always 或者 restart: on-failure,而個主應用程式容器因為等唔到依賴服務(超時)而失敗退出,咁 Docker 就會不斷嘗試重啟佢,形成一個重啟迴圈。為咗避免呢種情況,你可以考慮喺你個應用程式入面,加入更聰明嘅重試邏輯,而唔係單純依賴啟動時嘅一次過等待。又或者,設定一個 restart: unless-stopped 並配合監控,等工程師可以手動介入檢查問題。總而言之,容器啟動順序 同超時管理唔係 set-and-forget(設定完就唔理)嘅事,需要根據你實際嘅 多容器應用 特性,經過反覆測試同觀察,先可以搵到最平衡嘅設定。

docker compose wait - MongoDB

AboutMongoDBProfessional illustrations

點整自定義等待?

好啦,講完一啲現成工具,咁如果我哋啲服務好特別,或者有啲古怪嘅啟動條件,點整自定義等待呢?呢個就考功夫啦,但其實 Docker Compose 本身已經提供咗幾種彈性方法,等我哋深入拆解下。

首先,最經典嘅方法就係寫一個自己嘅 Shell Script,好似 wait-for-it.sh 嘅原理咁,但係 tailor-made 咁去配合你個服務。例如,你個 Rust 寫嘅微服務,可能唔係一聽個 TCP 端口就代表 Ready,佢可能要等內部初始化完成,寫個檔案去某個路徑先算得。咁你就可以喺你個應用程式嘅 Dockerfile 入面,加一個自定義嘅健康檢查腳本,或者喺 docker-compose.yml 入面,用 depends_on 配合 healthcheck 一齊玩。個 healthcheck 嘅 test 指令,就可以係你自訂嘅腳本,去檢查啲檔案有冇出現,或者用 curl 打個內部 API endpoint,睇下佢係咪真係準備好。咁樣,其他服務嘅 service dependency 就可以靠呢個 healthcheck 狀態去決定幾時啟動,完美解決容器啟動順序問題。

不過,自定義等待有個大陷阱,就係你個基礎鏡像有冇 Shell。如果你用緊 distroless 或者 scratch 呢類極簡鏡像,入面連個 Bash 都冇,咁你寫 Shell Script 就冇用武之地啦。咁點算?呢個時候就要諗辦法將等待邏輯 build 入你個應用程式本身。例如,你可以寫一段簡單嘅 Rust 或者 Go 程式,編譯成一個靜態二進制檔案,喺 Dockerfile 入面 COPY 入去。呢個小工具嘅唯一功能,就係不斷嘗試連接目標服務嘅特定端口,或者檢查某個條件,直到成功為止。因為係靜態編譯,唔依賴 MUSL 或者其他系統庫,就算喺 scratch 鏡像入面都可以直接運行。然後,你喺 docker-compose.yml 入面,就可以用 depends_on 下面加個 condition: service_healthy,而個健康檢查就係運行你呢個自編譯嘅等待工具。呢種方法對於容器生命週期管理好有彈性,尤其適合啲複雜嘅多容器應用。

另外,進階玩法仲可以考慮利用 Docker Compose 本身嘅 CLI 同環境變量配置去搞。例如,你可以寫一個自定義嘅命令行工具,當你運行 docker-compose up(或者 2026 年嘅 docker compose up)之前,先運行呢個工具去檢查一啲外部依賴,例如雲端嘅數據庫服務係咪通。又或者,你可以喺 docker-compose.yml 入面,用 environment 設定一啲變量,然後喺你個應用程式嘅入口點腳本入面,加入一段邏輯,去讀取呢啲變量,並據此決定等待邊個服務、等幾耐。雖然 Docker Docs 未必有直接講呢種 pattern,但 Stack Overflow 上面有好多高手分享呢類實戰技巧,特別係處理好似 MongoDB、MySQL、Postgres、RabbitMQ 呢啲有複雜啟動階段嘅服務時,自定義邏輯就非常好用。

最後都要提提,整自定義等待腳本時,一定要諗埋錯誤處理同超時設定。你唔可以無限等落去,否則個容器會卡死。通常都要設定一個最大重試次數同 startup delay。例如,等一個服務嘅端口,可以每兩秒試一次,試夠三十次都唔得就當失敗,跟住執行 restart policy 定係直接退出。呢啲細節對於確保成個 multiservice applications 嘅穩定性好緊要。總括來講,整自定義等待無非就係將你對服務依賴等待嘅理解,用腳本、健康檢查或者小型命令行工具嘅方式實現出嚟,等 Docker Compose 嘅容器編排可以更貼合你個應用嘅實際需要。

docker compose wait - MySQL

AboutMySQLProfessional illustrations

常見錯誤即解

好啦,講咗咁多 Docker Compose 等容器嘅方法,實戰時撞板嘅機會都唔少。呢度就同大家拆解幾個常見錯誤即解,等你唔使次次都去 Stack Overflow 撞手神。首先,好多人最易中伏嘅就係誤解咗 depends_on 嘅真正功能。好多新手以為,只要喺 docker-compose.yml 設定咗 depends_on,咁被依賴嘅服務(例如個 Postgres 數據庫)就一定會「準備好」先啟動依賴服務。但事實係,depends_on 只係控制容器啟動順序,即係個 Postgres 容器個進程會行先,但唔代表佢裏面個數據庫服務已經完成初始化、可以接受連線。呢個時候,如果你個應用程式容器即刻撲過去連線,好大機會會連線失敗,成個多容器應用就炒咗。所以,單靠 depends_on 來處理 service dependencies 係唔夠㗎。

咁點算好?正路嘅解決方案就係配合 healthcheck 指令。你可以喺被依賴嘅服務度,定義一個健康檢查,例如叫 Docker 每隔幾秒就用個命令或者檢查特定 TCP端口 嚟確認個服務(好似 MySQL 或者 RabbitMQ)係咪真係行得。等到佢個狀態變成 healthy,先至真正啟動依賴佢嘅服務。呢個先係完整嘅 服務依賴等待 策略。不過,寫 healthcheck 都要小心,例如檢查 MongoDB 同檢查 Postgres 嘅命令可能唔同,要睇返官方 Docker Docs 或者社群建議,設定唔正確嘅檢查命令可能令到個容器永遠都唔會變成 healthy,卡住成個 容器啟動順序

另一個常見錯誤,就係用錯工具或者用錯方法。例如,有人會喺自己個應用程式鏡像入面,直接放入 wait-for-it.sh 呢類腳本,然後喺 Dockerfile 嘅 ENTRYPOINT 度叫佢等某個端口。呢個方法本身冇問題,但如果你用咗 distroless 甚至係 scratch 呢類極簡基礎鏡像,問題就嚟啦:呢啲鏡像裏面可能連 Bash 或者 Shell 都冇,純粹係為咗行一個二進制檔案(例如用 RustGo 寫嘅應用),屬於無Shell環境。咁個腳本根本冇辦法執行。同樣道理,好似 docker-compose-wait 呢類工具,雖然好用,但佢本質上都係一個可執行文件,你要確保你個鏡像嘅文件系統路徑入面有相應嘅工具同埋佢所需嘅依賴(例如可能係 MUSL 呢類 C 庫),尤其係你要做跨平臺編譯嘅時候,更加要測試清楚。

仲有,環境設定都係伏位之一。無論你用邊種等待策略,好多時都需要透過環境變量配置嚟指定要等嘅主機名同端口。常見錯誤係直接寫死咗 "localhost" 或者 "127.0.0.1"。要記住,喺 Docker 嘅網絡入面,每個容器都有自己嘅主機名,服務之間應該用 Docker Compose 設定嘅服務名嚟溝通。如果你喺等待腳本或者工具嘅參數裏面寫死咗 "localhost",咁佢只會檢查自己容器內部嘅端口,永遠都等唔到另一個容器服務。正確做法係用服務名,例如等 "db:5432" 而唔係 "localhost:5432"。呢個概念對於容器編排嚟講好核心,就算你第日玩 Kubernetes 都係一樣。

最後,唔好忽略咗重啟策略 (restart policy) 同等待機制之間嘅互動。如果你為服務設定咗 restart: always,而個服務因為等唔到依賴服務而啟動失敗,佢就會不斷咁重試。如果冇配合適當嘅 startup delay(啟動延遲),可能會造成一個瘋狂重啟嘅循環,食爆你嘅 CPU。另外,當你要停止成個項目停止時,如果啲容器之間有複雜嘅等待關係,用 docker-compose down 或者 docker stack rm 時,都可能會有啲服務停得慢,影響到成個流程。呢啲都屬於容器生命週期管理嘅細節,需要因應自己個應用嘅特性去調整。總而言之,處理容器等待冇銀彈,關鍵在於理解清楚每個工具(無論係內置嘅 healthcheck、定係第三方 CLI)嘅原理同限制,再根據你個多服務應用嘅實際架構,設計一個穩陣嘅啟動同停止流程。

docker compose wait - Loginov

AboutLoginovProfessional illustrations

效能優化貼士

講到效能優化貼士,我哋首先要搞清楚,Docker Compose 入面嘅等待機制唔單止係「等到個服務行起嚟」,而係要「等到個服務 健康 地行起嚟,可以接受請求」。如果你淨係用 depends_on 呢個基本設定,佢只係控制 容器啟動順序,即係個 Container 會跟次序 start,但係唔會檢查入面個應用程式(例如個 database)係咪真係 ready 咗。呢個時候,你個 Web Server 可能已經急急腳連去個 Postgres 或者 MySQL 度,跟住就撞板,彈一堆 connection error 出嚟。所以,第一個最核心嘅貼士就係:一定要配合 healthcheck 指令一齊用。喺 Docker Compose 檔案入面,你可以為每個需要被等待嘅服務(例如 MongoDB、RabbitMQ)定義一個健康檢查指令,等 Compose 知道點樣先算係「健康」。咁樣,你嘅主服務(例如個 Rust API 或者 Node.js app)就可以喺 depends_on 入面設定 condition: service_healthy,真真正正等到所有依賴服務都就緒先至啟動,避免晒啲無謂嘅啟動失敗同自動重試,成個 多容器應用 嘅啟動就穩定同可靠好多。

跟住落嚟,我哋要諗下,係咪所有情況都要等?等幾耐先合理?呢度就涉及到 startup delayrestart policy 嘅策略性設定。好似 MySQL 同 Postgres 呢類數據庫,有時喺初次啟動或者恢復數據時,需要多啲時間先至可以接受連接。如果你個健康檢查設定得太急,可能未等到佢完全 ready 就判定為失敗,跟住成個 stack 停咗,或者不斷 restart,咁就弄巧反拙。一個實用嘅做法係,喺健康檢查指令入面加入一啲初始等待時間,或者用一啲專門嘅 TCP端口檢查 工具(好似係 wait-for-it.sh 嘅原理)去輪詢個端口,而唔係一嚟就試圖登入。另外,設定一個合理嘅 restart policy(例如 restart: unless-stopped)可以幫你處理一啲暫時性嘅問題,但如果係 服務依賴等待 嘅根本邏輯出錯,不斷重啟只會浪費資源,令到成個系統更慢。所以,優化嘅心法係:精準定義「健康」狀態,並給予足夠嘅啟動寬限期。

另一個好易被忽略嘅效能位,就係你用來做等待嘅工具本身。好多開發者貪方便,會喺容器入面安裝一啲完整嘅 Shell 同網絡工具(例如 curl 或者 nc)來做健康檢查或者運行等待腳本。但係咁樣會令到你個容器映像變得臃腫,增加咗安全風險同啟動時間。對於追求極致效能同安全嘅環境,你可以考慮使用 distroless 甚至係 scratch 映像作為基礎。咁問題嚟啦,冇咗 Shell,點樣做健康檢查同等待呢?解決方案有幾個:第一,盡量使用 Docker 內置嘅 healthcheck 指令,佢支援直接用 TCP 檢查或者 HTTP GET,唔需要額外工具。第二,如果邏輯複雜啲,可以考慮將等待邏輯寫入你應用程式本身嘅初始化代碼入面。第三,可以選用一啲極輕量嘅專門工具,例如官方有提及嘅 docker-compose-wait 或者用 Rust 編寫嘅靜態二進制文件,呢啲工具可以喺 多架構支持跨平臺編譯 後,直接放落 無Shell環境 入面運行,又細又安全。

最後,我哋要從宏觀嘅 容器編排 角度去諗。Docker Compose 本身係用嚟做本地開發同測試,對於生產環境,好多人會轉用 Kubernetes 或者 docker stack(配合 Docker Swarm)。呢個時候,等待同依賴管理嘅思維要升級。Kubernetes 有自己更完善嘅探針(liveness/readiness probe)同 Init Container 機制,功能強大好多。但係,你喺開發階段用 Docker Compose 設定好嘅 healthcheck,某程度上係為日後遷移去 Kubernetes 做準備,因為概念係相通嘅。另外,記得要善用 Docker CLIDocker Docs 嚟搵最新資訊,好似係 2026 年嘅今日,Docker Engine 同 Compose 版本可能已經有咗新嘅最佳實踐,或者解決咗舊版本喺 服務等待 上嘅一啲 bug(例如喺特定 MUSL 環境下嘅問題)。平時遇到難題,除咗去 Stack Overflow 睇下,亦可以留意下社區專家(好似係 Pavel Loginov 呢類)嘅分享,佢哋經常會深入剖析 容器生命週期管理 嘅細節。總而言之,效能優化唔係淨係追求快,而係追求穩定、可靠同資源高效,由設定精準嘅健康檢查,到選擇合適嘅工具,再到為未來編排鋪路,每一步都係學問。

docker compose wait - Postgres

AboutPostgresProfessional illustrations

多環境配置示範

講到多環境配置示範,我哋就要諗下點樣用 Docker Compose 嘅 depends_on 同 healthcheck 呢啲工具,去靈活處理唔同環境(例如開發、測試、生產)嘅服務依賴等待問題。好多香港嘅開發團隊都遇過類似情況:喺自己部 Mac 或者 Windows 機度,個 docker-compose.yml 行得好地地,點知一上到 CI/CD 流水線或者雲端嘅 Kubernetes 環境,成個多容器應用就因為容器啟動順序亂咗而出事。呢個就係典型嘅「環境差異」導致嘅服務依賴問題。所以,一個穩陣嘅多環境配置,唔可以只係靠 Docker Compose 嘅基礎 depends_on(佢只係保證啟動順序,唔會等服務真正 Ready),而係要結合健康檢查同等待策略。

首先,我哋要明白「服務等待」嘅核心邏輯。喺開發環境,你可能貪方便,用 wait-for-it.sh 呢類 Bash 腳本,去等某個 TCP端口檢查通過(例如等個 MySQL 嘅 3306 port 可以連線)。呢個方法簡單直接,但係佢有個大前提:你個容器入面要有完整嘅 Shell 環境。如果你用緊一啲極簡化嘅基礎映像,例如 distroless 或者甚至係 scratch,咁就無 Shell 比你行腳本,呢個方法即刻失效。所以,喺設計多環境配置時,第一個要考慮嘅就係「目標環境嘅容器特性」。對於無Shell環境,我哋就要諗第二啲方法,例如用 Docker 官方建議嘅方式,或者用一啲專為容器生命週期管理而設計嘅輕量級工具。

舉個具體例子,假設我哋有個典型嘅後端服務堆疊,入面有 Postgres、RabbitMQ 同一個用 Rust 寫嘅 API 服務。喺 docker-compose.yml 裡面,我哋可以點寫呢?對於開發同測試環境,我哋可以用一個比較全面嘅方法:為 Postgres 同 RabbitMQ 呢啲依賴服務定義明確嘅 healthcheck。健康檢查嘅指令可以好具體,例如用 pg_isready 去檢查 Postgres,用 rabbitmq-diagnostics check_port_connectivity 去檢查 RabbitMQ。然後,喺我哋個 Rust 服務嘅 depends_on 段落入面,就唔係單純寫 service: condition: service_started,而係升級做 condition: service_healthy。咁樣,Docker Compose 就會等到依賴服務嘅健康檢查通過先至啟動我哋嘅應用容器,確保咗服務依賴等待係有效嘅。

但係,生產環境或者一啲高要求嘅測試環境可能又唔同玩法。你可能會用緊 Docker Swarm(即係 docker stack deploy)或者直頭係 Kubernetes 去做容器編排。喺呢啲環境,Docker Compose 嘅 depends_on 係唔會被執行嘅!呢個係好多人都會中伏嘅位。所以,你嘅「等待邏輯」必須要內建喺應用程式本身或者 entrypoint 腳本裡面。呢個時候,我哋就要借助一啲跨平臺嘅命令行工具。例如,你可以考慮用一啲用 MUSL 編譯、靜態連結嘅細工具,佢哋可以好細粒,直接 COPY 入你個 distroless 映像度都得。呢類工具通常會提供命令行選項,讓你可以設定等待嘅主機、端口、超時時間,甚至係檢查某個文件系統路徑係咪存在,作為服務準備好嘅信號。咁樣就能夠實現真正嘅多架構支持同跨平臺編譯,無論你個容器行喺 x86_64 定係 arm64 嘅機器上都得。

另外,環境變量配置喺多環境示範入面都扮演關鍵角色。我哋可以喺 docker-compose.yml 入面利用環境變量文件(例如 .env.dev, .env.prod),或者直接喺 compose 文件度定義唔同嘅配置。例如,針對「等待」呢個行為,我可以設定一個環境變量叫 WAIT_TIMEOUT,喺開發環境設定為 60 秒,喺生產環境可能設定為 120 秒,因為生產環境嘅數據庫啟動可能涉及更多數據恢復步驟。又或者,我可以設定 WAIT_FOR_HOSTS,喺本地開發時,個值可能係 postgres:5432,rabbitmq:5672;但係喺某啲特定測試環境,服務名可能唔同,我就可以透過唔同嘅 .env 文件去覆寫呢個值,而唔使改動個 docker-compose.yml 本身。呢種方式令到配置好有彈性。

最後,重啟策略 restart policy 同啟動延遲 startup delay 嘅配合,喺多環境下都值得深思。喺生產環境,我哋可能會將服務設定為 restart: always,但係如果個服務因為等唔到依賴服務而不斷失敗重啟,就會造成重啟風暴。因此,喺個應用嘅啟動腳本或者工具入面,加入指數退避嘅延遲邏輯,或者利用 Docker Compose 本身嘅 restart 條件配合健康檢查,可以避免呢個問題。總而言之,構建一個健壯嘅多環境等待配置,需要你深入了解 Docker Docs 嘅建議、參考社區(如 Stack Overflow)上嘅實踐,並根據自己項目嘅技術棧(係用 Postgres 定係 MongoDB,係用 Rust 定係其他語言)來選擇最合適嘅組件同策略。目標係確保無論喺邊個環境,你嘅多服務應用都能夠以正確嘅容器啟動順序,平滑地完成初始化。

docker compose wait - RabbitMQ

AboutRabbitMQProfessional illustrations

CI/CD 整合心得

講到將 Docker Compose 嘅等待策略整合落 CI/CD 流水線,真係有血有淚,好多實戰經驗可以分享。喺 CI/CD 環境入面,成日都要處理多容器應用嘅啟動同測試,如果啲服務依賴等待做得唔好,成個 Pipeline 就會因為測試失敗而卡住。我哋最初試過用傳統嘅 depends_on,但好快就發現問題:depends_on 只係控制容器啟動順序,但唔會理個服務係咪真正準備好接受連接。例如個 Postgres 或者 MongoDB 容器可能已經行緊,但內部嘅資料庫仲未完成初始化,呢個時候個應用程式容器一連過去就會即時炒車,搞到自動化測試成日唔穩定。

所以,我哋嘅心得係,一定要將 healthcheck 指令同 depends_on 結合使用,呢個係 Docker Docs 都強烈建議嘅最佳實踐。喺個 docker-compose.yml 入面,我哋會為每個有依賴性嘅服務(例如資料庫、消息隊列好似 RabbitMQ)定義清晰嘅健康檢查。個健康檢查會用 CLI 工具或者簡單嘅 TCP 端口檢查去確認個服務真係 Ready。然後,依賴方嘅 depends_on 就可以加個 condition: service_healthy 落去,咁樣 Docker Compose 就會等到依賴服務健康先至啟動下一個容器,完美解決容器啟動順序嘅核心痛點。呢個方法比起單純用 wait-for-it.sh 呢類腳本去等待端口更為原生同可靠。

不過,喺 CI/CD 嘅無情世界,仲要考慮更多極端情況。例如,有啲服務健康檢查需要時間,我哋會適當加入 startup delay,避免一開始就不斷狂試造成誤判。另外,restart policy 嘅設定都好關鍵,特別係當某個服務因為依賴未準備好而啟動失敗時,應該點樣重試。我哋通常會設定為 restart: "on-failure",並配合一個最大重試次數,避免個容器無限 loop 拖死成個 Pipeline。

另一個深刻嘅教訓係關於環境配置。喺 CI 伺服器上,我哋可能用緊 distroless 甚至係 scratch 呢類極簡基礎映像來運行應用。呢類映像最大問題係裏面無 Shell,即係話傳統依賴 bash 或者 sh 嘅等待腳本(例如 wait-for-it.sh)會完全行唔到。呢個時候,我哋就要轉用純 Rust 或者 Go 編寫嘅靜態編譯等待工具,呢啲工具可以編譯成靜態二進制檔,直接抄入 scratch 映像度運行,完全唔需要任何外部依賴。好似 Pavel Loginov 維護嘅 docker-compose-wait 呢類項目嘅思路就好值得參考,雖然我哋最後可能係自己寫個輕量工具。

講到工具選擇,我哋會避免喺 CI 腳本入面寫死一大段複雜嘅 Shell 命令來處理服務等待。更好嘅做法係將等待邏輯封裝成一個獨立嘅 命令行工具,並通過環境變量配置來控制等待嘅超時時間、目標主機同端口。咁樣做,個 CI 配置(例如 .gitlab-ci.yml 或 GitHub Actions 嘅 workflow 檔)就會變得乾淨好多,只係簡單調用呢個工具,等待所有必需服務(例如 MySQLRabbitMQ)就緒,然後先執行測試命令。呢個工具仲可以加入文件系統路徑檢查,例如等某個初始化腳本完成生成,先至算服務準備好,非常靈活。

最後,仲有一點關於容器生命週期管理。喺 CI/CD 流水線嘅尾聲,無論測試成功與否,都要確保乾淨地停止同清理所有容器。直接用 docker-compose down 係基本,但如果用咗 docker stack 部署去 Swarm,就要用相應嘅 Docker CLI 命令。有時啲測試會改動容器狀態或者掛載 volume,如果唔清理乾淨,下次 Pipeline 運行就可能會受到污染。我哋嘅做法係,喺 CI 腳本嘅 after_script 或者 finally 階段,強制執行清理命令,確保環境純淨。總括來講,將等待策略整合到 CI/CD,核心思想就係要「確定性」:確保每次 Pipeline 運行時,應用程式面對嘅後端服務狀態都係一致且準備好嘅,咁先可以建立起穩定可靠嘅自動化部署流程。

docker compose wait - Rust

AboutRustProfessional illustrations

2026 新功能應用

講到2026年Docker Compose嘅新功能應用,我哋首先要提嘅係佢對服務依賴等待容器啟動順序嘅處理,已經進化到一個全新境界。以往我哋要等MongoDB或者Postgres完全準備好先至啟動個App,成日都要搵wait-for-it.sh或者docker-compose-wait呢類第三方工具,又或者喺depends_on加埋healthcheck去模擬等待,但係去到2026年,Docker Compose嘅內置等待機制已經變得非常智能同完善。依家嘅docker-compose.yml可以直接定義更精細嘅service dependencies,例如可以設定唔單止係等個容器運行(status: running),而係要等佢嘅健康檢查(healthcheck)真正通過,甚至係等某個特定嘅TCP端口檢查(wait for port)成功,先至算係依賴服務準備就緒。呢個改動對於構建可靠嘅多容器應用(multiservice applications)嚟講,真係省咗好多功夫,唔使再自己寫一堆Script去輪詢端口或者檢查文件系統路徑

另外,2026年Docker生態同Kubernetes嘅整合又再深入咗一層。雖然Docker Compose本身係用嚟做本地開發同輕量級容器編排,但係而家佢嘅一部分配置同語法,已經可以更無縫咁轉換成K8s嘅資源定義。呢個對於團隊由開發到上生產環境嘅流程好有幫助,減少咗配置不一致嘅問題。同時,Docker CLI同Docker Docs亦都大力推廣點樣用Compose去定義同管理更複雜、更貼近生產環境嘅堆棧,甚至係用docker stack deploy到Swarm嘅場景。

講到實際應用例子,假設我哋有個2026年典型嘅微服務項目,入面有Rust寫嘅API服務、一個Postgres資料庫、一個RabbitMQ消息隊列。以往我哋可能會擔心個Rust服務啟動得太快,但係個Postgres仲未完成初始化同建立好所需嘅資料庫。依家嘅做法可以好直接:喺Compose文件裏面,對我哋個Rust服務嘅depends_on部分,明確指明要等Postgres服務達到「healthy」狀態。而Postgres服務嘅healthcheck定義,可以好精確咁檢查資料庫埠同埋執行一個簡單查詢去確認就緒。咁樣就完全唔需要額外嘅外部等待工具,純粹用Docker Compose原生功能就搞掂晒容器生命週期管理中嘅啟動協調問題。

仲有一個好實用嘅新功能,係關於環境變量配置無Shell環境嘅支持。以前如果我哋用scratch或者distroless呢類極簡基礎映像去運行應用,想喺啟動時做一啲簡單嘅等待或者條件檢查係好困難嘅,因為入面可能連Shell都無。去到2026年,Docker Compose引入咗一種新嘅「初始化容器」概念(類似K8s嘅init container),或者係喺主容器啟動指令之前,可以插入一啲由Docker提供嘅、輕量級且多架構支持嘅通用等待步驟。呢啲步驟係獨立嘅微容器,專門用嚟執行等待邏輯,例如檢查另一個服務嘅端口或者URL,成功之後先至真正啟動我哋嘅主應用容器。呢個設計完美解決咗無Shell環境下點樣實現服務等待嘅老大難問題。

最後不得不提,社群嘅貢獻同需求一直推動住Docker Compose發展。好似開發者Pavel Loginov或者其他活躍於Stack Overflow同GitHub嘅朋友,佢哋提出嘅關於容器等待restart policystartup delay嘅各種複雜用例,好多都已經喺2026年嘅新版本中得到內置支持。所以,而家我哋處理服務依賴等待呢類問題,第一時間應該係去睇吓最新版嘅Docker Docs,而唔係即刻去Google搵第三方Script。總括嚟講,2026年嘅Docker Compose,已經將「等待」呢個基礎但關鍵嘅任務,從一個需要自己東拼西湊嘅Hack,變成一個穩定、聲明式、同埋功能豐富嘅內置模組,令到我哋開發同部署多容器應用更加順暢同可靠。

Frequently Asked Questions

What does Docker Compose --wait do?

Docker Compose 的 `--wait` 選項用於在啟動服務後,等待所有容器進入健康狀態。這確保了依賴服務在應用程式主邏輯執行前已準備就緒,對於微服務架構尤其重要。它避免了因服務啟動順序導致的連線錯誤。

  • 主要功能:阻塞執行直到所有服務的 `healthcheck` 指令回報為健康。
  • 使用場景:在執行 `docker compose up` 後,需要確保資料庫、訊息佇列等依賴服務完全就緒。
  • 指令範例:`docker compose up --wait`,可搭配 `--wait-timeout` 設定最長等待時間。

What does docker wait do?

`docker wait` 是一個 Docker CLI 指令,用於阻塞並等待一個或多個容器停止運行,然後輸出它們的退出代碼。這在自動化腳本中非常有用,可以用來同步容器任務的完成狀態。它與 `docker compose --wait` 的用途不同,後者是等待服務健康。

  • 核心用途:監聽容器停止事件並獲取其退出狀態碼。
  • 常用指令:`docker wait `。
  • 腳本整合:常與 `docker run` 搭配,用於批次處理或任務編排。

What is wait-for-it.sh and how is it used with Docker Compose?

`wait-for-it.sh` 是一個流行的 Bash 腳本,用於測試主機和埠的 TCP 連線是否就緒。在 Docker Compose 中,它常用於容器啟動指令(`CMD` 或 `entrypoint`)中,確保當前容器等待其依賴的服務(如資料庫)啟動完成後,才啟動自身應用。這是一種服務依賴管理的經典模式。

  • 主要目的:實現簡單的服務啟動順序控制。
  • 使用方法:在 Dockerfile 或 Compose 指令中,於應用啟動前執行 `wait-for-it.sh host:port`。
  • 與內建功能對比:在 2026 年,Docker Compose 的 `--wait` 及健康檢查功能已能處理多數情況,但此腳本在特定自定義場景仍有價值。

Is Docker Compose obsolete in 2026?

不,Docker Compose 在 2026 年並未過時,它仍然是本地開發、測試和單主機部署的標準工具。隨著雲原生生態發展,它與 Kubernetes 的整合(如透過 Kompose 轉換)及 Docker Compose V2 的持續更新,使其在定義多容器應用方面保持關鍵地位。它簡化了開發者體驗,並非被取代,而是生態位更清晰。

  • 現狀:仍是開發和 CI/CD 管道的首選工具之一。
  • 發展:V2 版本效能提升,並支援更多現代部署選項。
  • 定位:專注於「編排」的入門與開發階段,而非大規模生產編排。

Is Docker still relevant in 2026?

是的,Docker 在 2026 年依然非常相關。作為容器技術的事實標準,它構建了整個雲原生應用的基礎。雖然無伺服器(Serverless)和 WebAssembly 等技術在某些領域興起,但 Docker 的龐大生態、工具鏈支援及與 Kubernetes 的深度整合,確保了其在應用程式打包、分發和運行中的核心地位。

  • 生態優勢:擁有最大的公共映像庫(Docker Hub)和豐富的工具鏈。
  • 技術整合:與 Podman 等工具相容,並持續改進安全性和效能。
  • 企業應用:仍是微服務和 DevOps 實踐中不可或缺的一環。

How to make Docker Compose build faster in 2026?

在 2026 年,加速 Docker Compose 構建主要依賴於利用快取、分層最佳化以及新工具。確保 Dockerfile 編寫良好,並使用 BuildKit 的進階功能是關鍵。此外,合理組織 `docker-compose.yml` 和利用雲端構建快取也能大幅提升速度。

  • 使用 BuildKit:設定 `DOCKER_BUILDKIT=1`,利用其並行構建和增量快取能力。
  • 最佳化 Dockerfile:將不常變動的指令(如安裝套件)放在前面,以最大化快取利用。
  • 映像策略:對基礎服務直接使用官方映像而非自建,並考慮使用 `--no-cache` 僅在必要時完全重建。

What does 0.0.0.0 mean in Docker networking?

在 Docker 網路中,`0.0.0.0` 是一個特殊的 IP 地址,表示「所有可用的網路介面」。當你在 Docker Compose 中將服務埠綁定到 `0.0.0.0:8080` 時,意味著該容器服務將在主機的所有 IP 地址(包括本地迴環 127.0.0.1 和區域網路 IP)上的 8080 埠監聽。這通常用於允許從主機外部存取容器服務。

  • 安全注意:將服務暴露在 `0.0.0.0` 可能帶來安全風險,需配合防火牆規則。
  • Compose 設定:在 `ports` 區段通常寫為 `- "8080:8080"`,預設即綁定到 `0.0.0.0`。
  • 替代方案:若僅需本機存取,可明確指定為 `- "127.0.0.1:8080:8080"`。

How to make Docker run faster in 2026?

提升 Docker 運行速度涉及多個層面,包括主機系統配置、儲存驅動程式選擇和資源分配。在 2026 年,使用最新的 Docker 版本並啟用諸如惰性載入(lazy-pull)等實驗性功能,可以顯著減少容器啟動時間。此外,合理分配 CPU 和記憶體限制也至關重要。

  • 儲存驅動:在 Linux 上優先使用 `overlay2`,並確保有足夠的磁碟 I/O 效能。
  • 資源配置:在 `docker-compose.yml` 中為服務設定適當的 `cpus` 和 `mem_limit`,避免資源爭奪。
  • 系統調整:增加 Docker 守護行程的記憶體與 CPU 資源,並考慮使用 SSD 儲存。

在 Docker Compose 中,除了 --wait,還有哪些方法可以控制服務啟動順序?

除了使用 `--wait` 選項,在 Docker Compose 中控制服務啟動順序主要有三種方法:依賴聲明、健康檢查結合條件指令,以及外部等待腳本。最佳實踐是使用內建的 `depends_on` 配合健康檢查條件,這在 Compose 規範 V2 及以上版本中得到良好支援。

  • `depends_on`:聲明服務依賴關係,確保啟動順序,但不會等待目標服務「就緒」。
  • 健康檢查條件:在 `depends_on` 中使用 `condition: service_healthy`,等待依賴服務通過健康檢查。
  • 自定義腳本:在容器啟動指令中嵌入如 `wait-for-it.sh` 的腳本,進行更靈活的埠或 API 檢查。

使用 Docker Compose 的 --wait 功能時,如何設定超時時間以避免無限期等待?

使用 `docker compose up --wait` 時,可以透過 `--wait-timeout` 旗標來設定最大等待時間(以秒為單位),避免因某個服務始終無法健康而導致指令無限期掛起。這是確保自動化流程可靠性的關鍵設定。例如,`docker compose up --wait --wait-timeout 120` 表示最多等待 120 秒。

  • 指令格式:`--wait-timeout <秒數>`。
  • 預設行為:如果未指定,可能會使用 Compose 檔案中健康檢查的 `interval` 和 `retries` 設定來影響等待邏輯。
  • 錯誤處理:超時後,指令會以非零代碼退出,並可據此在 CI/CD 管道中觸發失敗處理流程。