SSD Nodes Learn 🎉 VPS $4.99/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-07

Docker Compose 實際伺服器常用指令懶人包

整理伺服器上每天會用到的約 12 個 Docker Compose 指令,涵蓋啟停、套用變更、logs、shell、network、volume,以及安全清理。

你實際會用到的 Compose 指令

Docker Compose 提供超過 40 個子指令。在伺服器上的日常工作通常只會用到約 12 個。本頁依工作目的整理這些指令,為每個指令說明一個直接原因,並在指令容易隱藏問題時,提供深入說明的連結。

本頁所有內容都使用 Compose V2:docker compose(中間有空格),而不是舊版的 docker-compose script。V2 是隨 Docker Engine 安裝的 Go plugin。V1 已從目前的套件中移除,因此截至 2026 年 7 月,在全新的 Ubuntu 主機上使用 docker-compose: command not found 是預期行為,不代表發生錯誤。使用 docker compose version 檢查。如果沒有輸出,請安裝 docker-compose-plugin package。

以下每個指令都必須從包含 compose.yaml 的目錄執行,因為 Compose 會從該目錄取得 project name,並以該目錄為基準尋找檔案。在上一層目錄執行相同指令時,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 會建立 network、建立容器、啟動容器,然後返回。它會在容器「建立完成」後立即返回,因此部署指令碼若緊接著執行 curl 探查,第一次通常會失敗。up -d --wait 會持續等待,直到所有宣告 healthcheck 的服務都回報 healthy;如果其中一個服務始終未達到此狀態,命令會以非 0 狀態碼結束。這個 flag 的效果取決於背後的檢查,因此在自動化流程中使用前,請先撰寫 Compose 可以信任的 healthcheck

stop 會停止容器但保留容器,因此 start 會使用相同的可寫入層重新啟動相同的容器。down 會停止容器,接著移除容器與 project network。容器內寫入且不在 volume 中的任何資料,都會隨容器一併移除。這是 Compose 中代價最高的誤解,而 down 與 stop 的完整差異 說明了它會在哪些情況造成影響。

restart 不是 reload。它會使用現有設定停止並啟動相同的容器,因此變更環境變數、新增 image tag 或修改 port mapping 都完全不會生效。若要套用檔案變更,必須再次執行 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 會略過這項比較,即使設定完全相同,也會替換每個容器,因此是清除容器內異常狀態最快的方法。

更新 image 需要執行兩個命令,因為兩者的作用不同。pull 會下載檔案中每個指定 tag 的最新 image。接著,up -d 會發現服務的 image ID 已與目前執行中的容器不一致,並重新建立該容器。若略過 pull,up -d 會讓上個月的 latest 持續執行,而且不會顯示錯誤。

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

查看正在執行的項目

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 專案及其狀態,讓你找出三個月前啟動的 stack。

在服務內取得 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 可略過服務的相依項目,避免快速檢查設定時啟動整個資料庫。

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

網路、連接埠與名稱解析

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

Compose 會將所有服務放在同一個專案網路上,每個服務名稱也會是該網路上的 DNS 名稱。在 web 內執行 getent hosts db 時,名稱解析成功會輸出容器 IP;解析失敗則不會輸出任何內容。因此,兩秒內即可確認「這些容器能否互相連線」。如果名稱可解析但連線遭拒,表示 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 會連同容器一併移除這些具名磁碟區。這是拆除測試 stack 的正確指令,但不適合用於儲存重要資料的環境,因為它不會要求確認,也無法復原。Bind mount 不受此操作影響,因為資料位於主機檔案系統中。這種影響範圍的差異,是應審慎選擇 bind mount 與具名磁碟區 的原因之一。

釋放磁碟空間且不遺失資料的清理方式

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

--remove-orphans 會刪除屬於該專案、但不再出現在檔案中的容器。服務重新命名後,就會產生這種情況。如果不執行此指令,這些容器會持續執行,而 docker compose ps 看不到它們。

docker system df 會在刪除任何內容前,顯示磁碟空間的使用情況,並分別列出映像、容器、local volumes 與 build cache,以及各項可回收的空間。image prune -a 會移除沒有任何 tag 指向的映像。如果伺服器曾拉取大型映像的多個版本,通常可釋放最多空間。builder prune 會清除 build cache。任何自行建置映像的伺服器,其 build cache 都會在背景中持續增加。

上述指令都不會處理 named volume。只有 docker volume prunedocker compose down -v 會處理 named volume。

在造成問題前檢查檔案

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 將執行的所有動作,但不會變更任何內容。對重要的 stack 而言,在執行 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 的服務,以及未標記 profile 的服務,讓除錯工具不會出現在一般的 up 中。-p 會設定專案名稱,因此同一個 stack 的兩個副本可以並行執行,並使用不同的 network 與 volume 名稱。重新開機後恢復 stack 並不是手動輸入的指令,而是由一個替你執行的 unit 完成;相關說明請參閱在開機時啟動 Compose stack

FAQ

docker-compose 改成含連字號的形式後,什麼取代了它?

Compose V2,使用 docker compose(中間有空格)執行。它是隨 Docker Engine 附帶的 plugin,而目前的套件已不再安裝 V1 Python 工具。如果空格形式沒有輸出,請為所用的發行版安裝 docker-compose-plugin 套件。請將舊腳本更新為空格形式,不要新增 alias,因為 V2 支援許多 V1 沒有的 flags。

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

restart 會使用建立現有 container 時的設定停止並重新啟動該 container,且不會重新讀取 compose.yaml。環境變數、連接埠、volume 或 image tag 的任何變更,都需要執行 docker compose up -d;此命令會比較每個 service 與其執行中的 container,並重新建立有差異的 container。如果希望即使檔案沒有變更也強制重新建立,請加入 --force-recreate

如何將 service 更新為較新的 image?

先執行 docker compose pull,再執行 docker compose up -d。pull 會為檔案中的每個 tag 取得目前的 image,而 up -d 會重新建立 image ID 與其 container 不一致的 service。單獨執行 up -d 時會重複使用磁碟上已有的 image。因此,固定使用 latest 的 stack 可能會持續使用數個月前的 build,且不會顯示任何錯誤。

在正式運作中的伺服器上,哪些清理命令是安全的?

docker system dfdocker image prune -adocker builder prune 只會移除 image 與 cache,因此執行中的 service 會繼續運作,named volume 也不會受到影響。危險的是 docker compose down -vdocker volume prune,這兩個命令會直接刪除 named volume,不會提示確認。請先執行 docker compose config --volumes,確認可能受影響的項目。

可以不啟動整個 stack,只執行一個命令嗎?

可以。docker compose run --rm --no-deps web sh 會根據 web service 定義啟動單一 container、略過其相依服務,並在離開時移除該 container。如果 container 已在執行,請改用 exec,因為 exec 會加入執行中的 process,讓你看到 service 的實際狀態。