SSD Nodes Learn 8GB 記憶體 — 每年 $66
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-01

Docker Compose 伺服器日常指令速查表

整理 Docker Compose V2 在伺服器上最常用的約 12 個指令,依生命週期、套用變更、日誌、shell、網路、volume 與安全清理分類。

你實際會使用的 Compose 指令

Docker Compose 發布的子命令超過 40 個。在伺服器上的日常工作通常只會使用約 12 個。本頁依工作內容將這些指令分組,為每個指令說明一個明確原因,並在指令容易造成問題時,提供深入說明的連結。

本頁所有內容都使用 Compose V2:docker compose,中間有空格,而不是舊版的 docker-compose 指令碼。V2 是隨 Docker Engine 安裝的 Go 外掛程式。V1 已不再包含於目前的套件中,因此截至 2026 年 7 月,在全新的 Ubuntu 主機上看到 docker-compose: command not found 是預期行為,不代表系統損壞。請使用 docker compose version 檢查。如果沒有任何輸出,請安裝 docker-compose-plugin 套件。

以下每個指令都必須從存放 compose.yaml 的目錄執行,因為 Compose 會從該目錄取得專案名稱,並以該目錄為相對位置尋找檔案。在上一層目錄執行相同指令時,Compose 會停止並顯示 no configuration file provided: not found。如果你還不熟悉檔案格式,請先閱讀VPS 上的第一個 Compose 檔案,再回到此處查看指令。

生命週期:你會輸入的 4 個指令,以及會移除容器的 1 個指令

docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose down

up -d 會建立網路、建立容器、啟動容器,然後返回。容器一經建立,它就會返回。因此,部署指令碼若在其後立即執行 curl 探測,第一次通常會失敗。up -d --wait 會持續等待,直到所有宣告 healthcheck 的服務都回報 healthy;如果其中任何服務始終未達到此狀態,則會以非零狀態結束。此旗標的效果取決於其背後的檢查,因此在自動化流程中使用前,請先撰寫 Compose 可以信任的 healthcheck

stop 會停止容器但保留容器,因此 start 會使用相同的可寫入層重新啟動相同的容器。down 會停止容器,接著移除容器和專案網路。寫入容器內、但位於 volume 外部的任何內容都會隨容器一併移除。這是 Compose 中代價最高的誤解,而 down 與 stop 的完整差異 說明了其影響範圍。

restart 不是重新載入。它會使用現有設定停止並啟動相同的容器,因此變更後的環境變數、新的映像標籤或修改後的連接埠對應完全不會生效。若要套用檔案變更,請再次執行 up -d。Compose 會將每項服務與其執行中的容器進行比較,只有設定已變更的服務才會重新建立。

套用變更:重新建立、提取或重建

docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build web

在沒有任何變更時,單獨執行 up -d 不會進行任何操作,因此可以安全地重複執行。--force-recreate 會略過比較,並在設定完全相同時仍替換每個容器,因此這是清除容器內異常狀態最快的方法。

更新映像需要執行兩個命令,因為兩者的作用不同。pull 會下載檔案中每個指定標籤的最新映像。接著,up -d 會發現服務的映像 ID 不再符合正在執行的容器,並重新建立該容器。略過提取步驟時,up -d 會繼續執行上個月的 latest,且不會顯示錯誤。

build 適用於宣告 build: 區段而非 image: 的服務。up -d --build 會在單一步驟中完成建置並啟動,這是在修改程式碼期間的標準流程。只有在快取層明顯過時時才使用 --no-cache,因為它會從頭重建每個層。

查看正在執行的內容

docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose ls

ps 只會列出正在執行的容器。啟動期間發生當機的服務,在加入 -a 之前不會顯示。因此,某個容器未出現在 ps 中,但 ps -a 將其顯示為 Exited (1),這正是啟動失敗的常見情況。先讀取結束代碼,再讀取日誌。

logs -f 會同時追蹤所有服務,並在每行前加上服務名稱。當服務彼此通訊且事件順序很重要時,這正是所需的檢視方式。指定服務名稱即可縮小範圍。對於已執行一個月的容器,--tail=100 很重要,因為預設會輸出完整歷程,讓終端機充滿內容。--since 15m 可回答您通常想知道的問題,也就是剛才執行重新啟動期間發生了什麼事。

top 會列出每個容器內的處理程序,協助區分「容器正在執行」與「容器內的處理程序正在執行」。ls 會離開目前的目錄,列出主機上的所有 Compose 專案及其狀態,讓您找到三個月前啟動的堆疊。

在服務內取得 shell

docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web sh

exec 會在已經啟動的容器內執行命令。run 會根據相同的服務定義啟動新的容器;當服務存活時間不足以讓您使用 exec 進入時,就必須使用此命令。請一律將 run--rm 搭配使用,否則每次執行都會留下已停止的容器,這些容器會持續累積,直到 docker compose ps -a 無法讀取。

請先嘗試 sh,再使用 bash。以 Alpine 為基礎的映像不包含 bash,失敗時會顯示 exec: "bash": executable file not found in $PATH。將 --no-deps 加入 run 可略過服務的相依項目,避免快速設定檢查啟動整個資料庫。

在所有 .env 檔案、environment: 區塊和 shell 變數合併後,run --rm web env 是查看服務實際取得之環境的最快方式。值不正確時,通常是合併順序造成的;Compose 如何解析環境檔案與 secrets 說明哪個來源具有優先權。

網路、連接埠與名稱解析

docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networks

Compose 會將所有服務放在同一個專案網路上,每個服務名稱都是該網路上的 DNS 名稱。在 web 內執行 getent hosts db 時,如果名稱解析成功,會輸出容器 IP;如果解析失敗,則不會輸出任何內容。因此,您可以在 2 秒內確認「這些容器是否能互相連線」。如果名稱可以解析,但連線遭拒,表示 db 內的程序繫結至 127.0.0.1,而不是 0.0.0.0,因此不會接受來自其他容器的封包。其餘模型說明請參閱Compose 網路與服務 DNS 的運作方式

port web 80 會輸出容器連接埠所發布至的主機位址與連接埠。當對應值來自變數時,這可避免猜測。發布連接埠也會寫入由 Docker 自行管理的防火牆規則,而該規則優先於您建立的規則。因此,您以為是私有的服務可能會對網際網路開放。相關情況請參閱Docker 發布的連接埠為何會繞過 ufw

磁碟區與資料

docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -v

config --volumes 會逐行列出專案宣告的具名磁碟區。您必須備份這份清單中的磁碟區。cp 可在不開啟 shell 的情況下,將檔案複製到容器或從容器複製出來;容器所在的一側使用 service:path 格式。

down -v 會連同容器一起移除這些具名磁碟區。這是拆除測試堆疊的正確指令,但不適用於任何包含重要資料的項目,因為它不會要求確認,也無法復原。繫結掛載不受此指令影響,因為它們位於主機檔案系統中。這種影響範圍的差異,也是您應審慎選擇繫結掛載與具名磁碟區的原因之一。

不遺失資料的磁碟清理

docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune

--remove-orphans 會刪除屬於此專案、但不再出現在檔案中的容器。服務重新命名後,就會產生這種情況。未使用此選項時,這些容器會持續執行,且在 docker compose ps 中不可見。

docker system df 會在刪除任何項目之前,顯示磁碟空間的使用情況,並分別列出映像、容器、本機磁碟區和建置快取,以及各項可回收的空間。image prune -a 會移除沒有任何標籤指向的映像。在已擷取大型映像多個版本的伺服器上,這通常能回收最多空間。builder prune 會清除建置快取。在自行建置映像的伺服器上,這項快取會持續增加,通常不易察覺。

上述指令都不會處理具名磁碟區。只有 docker volume prunedocker compose down -v 會處理具名磁碟區。

檢查檔案,避免造成問題

docker compose config --quiet
docker compose config --services
docker compose --dry-run up -d

config --quiet 會執行驗證,成功時不會輸出任何內容,因此適合放在部署前步驟或 git hook 中。單獨執行 config 會輸出完整合併並插值後的檔案。您可以藉此確認變數是否解析成功,以及覆寫檔案是否依預期套用。未設定的變數會顯示為空值,並在旁邊顯示警告 The "X" variable is not set. Defaulting to a blank string.

--dry-run 是全域旗標,不是子命令旗標,因此必須放在 up 之前。它會列出 Compose 將執行的每個動作,但不會變更任何內容。在重要的堆疊上執行 down 前,花費這 30 秒進行確認是值得的。

跨檔案、設定檔與專案工作

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -d

多個 -f 旗標會依序合併,後面的檔案會逐項覆寫前面的檔案。這是保留一個基礎檔案,再搭配小型 production 覆寫檔的標準方式。不過,清單與對應的規則不同,因此在疑難排解意外結果前,請先閱讀Compose 如何合併多個檔案

--profile 會啟動標記了該 profile 的服務,以及未標記的服務,讓偵錯工具不會出現在一般的 up 中。-p 會設定專案名稱,因此同一個 stack 的兩個副本可以並行執行,並使用各自的網路與 volume 名稱。重新啟動後恢復 stack 不需要手動輸入指令,而是由會代為執行的 unit 完成;相關說明請參閱在開機時啟動 Compose stack

FAQ

什麼取代了帶連字號的 docker-compose

Compose V2 以帶空格的 docker compose 呼叫。它是 Docker Engine 隨附的外掛程式,目前的套件不再安裝 V1 Python 工具。如果帶空格的形式沒有輸出,請為您的發行版安裝 docker-compose-plugin 套件。請將舊指令碼更新為帶空格的形式,不要新增別名,因為 V2 支援 V1 沒有的旗標。

為什麼 docker compose restart 沒有套用我的設定變更?

restart 會使用建立現有容器時的設定停止並啟動該容器,而且不會重新讀取 compose.yaml。環境變數、連接埠、磁碟區或映像標籤的任何變更,都需要使用 docker compose up -d。它會比較每項服務與其執行中的容器,並重新建立有差異的服務。如果希望即使檔案沒有變更也強制重新建立,請加入 --force-recreate

如何將服務更新為較新的映像?

執行 docker compose pull,然後執行 docker compose up -d。pull 會為檔案中的每個標籤擷取目前的映像,up -d 會重新建立映像 ID 與其容器不再相符的服務。單獨執行 up -d 會重複使用磁碟上已有的映像。因此,固定使用 latest 的堆疊可能持續使用數個月前的建置版本,且不會顯示任何錯誤。

哪些清理命令可安全地在使用中的伺服器上執行?

docker system dfdocker image prune -adocker builder prune 只會移除映像與快取,因此執行中的服務會繼續運作,具名磁碟區也不會受影響。危險的是 docker compose down -vdocker volume prune,這兩個命令會在不提示的情況下刪除具名磁碟區。請先執行 docker compose config --volumes,確認可能受到影響的項目。

可以只執行一個命令而不啟動整個堆疊嗎?

可以。docker compose run --rm --no-deps web sh 會根據 web 服務定義啟動單一容器、略過其相依項目,並在您離開時移除該容器。如果容器已在執行,請改用 exec,因為 exec 會連線至使用中的程序,並顯示服務目前的實際狀態。