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

Docker Compose stop 與 down 有什麼差別?

stop 只停止並保留容器;down 會移除容器與專案網路,但不刪除具名磁碟區。只有加入 --volumes 才會刪除資料。

簡短答案

docker compose stop 會停止容器,但將容器保留在磁碟上。docker compose down 會停止容器,接著刪除容器以及 Compose 為該專案建立的網路。這兩個指令都不會影響具名磁碟區。只有加入 -v 時,資料庫才會被刪除,如 docker compose down -v 所示;該選項會移除 Compose 檔案中 volumes 區段所宣告的具名磁碟區。

以上就是兩者的完整差異。接下來的指南會透過 Postgres 磁碟區示範這項差異:觀察它在執行 down 後仍然存在,並在執行 down -v 後消失;同時說明需要使用 --force-recreate 的兩種情況。

docker compose stop:容器仍然存在

stop 會向每個容器中的主程序傳送 SIGTERM,等待一段時間;如果程序仍在執行,接著會傳送 SIGKILL。預設等待時間為 10 秒,-t 可變更此設定。此命令不會刪除任何項目。容器會保留其 ID、可寫入層、IP 保留設定及記錄。

docker compose stop
docker compose ps -a

docker compose ps 單獨使用時只會顯示執行中的容器,因此在執行 stop 後,它會輸出空白資料表,讓人以為容器已經消失。ps -a 會包含已停止的容器;在其中,你會看到每個服務旁標示 Exited (0)。使用 docker compose start 即可重新啟動容器,且會重複使用完全相同的容器。

由於容器仍然存在,寫入容器內但不在 volume 中的任何內容也會保留。其中包括使用 docker compose exec 手動安裝的套件,以及在容器內編輯的設定檔。這就是除錯時偏好使用 stop 的實際原因:你可以在相同狀態下重新啟動。

docker compose down:移除容器和網路

down 會停止容器,接著移除容器,以及 Compose 為專案建立的預設網路。Docker 文件將其描述為停止容器,並移除由 up 建立的容器、網路、磁碟區和映像檔;但只有在使用 -v--rmi 要求時,才會移除磁碟區和映像檔。

docker compose down
docker compose ps -a
docker network ls

執行 down 後,ps -a 不會列出該專案的任何內容,<project>_default 網路也會消失。除非您在 Compose 檔案中設定 name:,或傳入 -p,否則專案名稱會取自目錄名稱。您在容器可寫入層中所做的所有變更現在都無法復原。因此,請將 down 視為會丟棄容器、但保留您存放在磁碟區中的資料的命令。

如果在錯誤的目錄中執行,您會收到 no configuration file provided: not found。Compose 不知道您指的是哪個專案,因此會拒絕執行。不在專案資料夾中時,請使用 docker compose -f /srv/myapp/compose.yaml down

docker compose down 會刪除我的磁碟區嗎?

不會。在頂層 volumes 索引鍵下宣告的具名磁碟區,其生命週期會超過 down,也會超過曾連接該磁碟區的容器。這是使用此命令時最常見的疑慮,而在 Compose v2 中,答案始終相同。

建立一個可供測試的堆疊。在名為 voltest 的空目錄中,將以下內容放入 compose.yaml

services:
  db:
    image: postgres:16.4
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

啟動堆疊,並寫入一列稍後可辨識的資料。

docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"

現在刪除容器,然後檢查磁碟區。

docker compose down
docker volume ls

輸出仍會列出 voltest_pgdata。容器已刪除,但資料仍在。重新啟動堆疊,然後讀取該列。

docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"

您會取得一列包含 survived 的資料。新容器是不同的容器,具有不同的 ID,但連接至相同的磁碟區。如需更完整的說明,Compose 基礎指南介紹具名磁碟區與繫結掛載的差異,以及每一種掛載實際位於主機上的位置。

exactly what down -v destroys

-v(完整形式為 --volumes)會移除 Compose 檔案中 volumes 區段所宣告的具名磁碟區,以及附加至容器的匿名磁碟區。請對相同的堆疊執行此命令。

docker compose down -v
docker volume ls

voltest_pgdata 不會再列出。再次啟動堆疊後,Postgres 進入點會發現空的資料目錄,因此初始化新的叢集。容器記錄會以明確文字顯示此結果。

The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.

在已執行數個月的堆疊中看到這段內容,表示磁碟區已被移除。您的 marker 資料表已消失,唯一的復原方式是使用備份。

-v 永遠不會移除某些儲存內容。繫結掛載使用主機路徑,因此 Docker 只會卸載它,檔案仍會保留在原處。標記為 external: true 的磁碟區宣告其所屬資源位於此專案之外,Compose 絕不會移除它。在執行 down -v 之前,若您已從 Compose 檔案中刪除具名磁碟區,該磁碟區便不再是已宣告資源,因此 Compose 不知道要移除它,並會將其作為孤立資源保留至 docker volume prune

最後一種情況常在人員重構設定時造成問題。從檔案中移除服務及其磁碟區後執行 down -v,該磁碟區仍會保留,因為檔案已不再提及它。請在編輯檔案之前執行 down -v,不要在編輯之後執行。

實際需要 --force-recreate 的情況

docker compose up -d 不會每次都重建所有內容。Compose 會將每個服務的解析後設定雜湊值,以標籤形式儲存在容器上。如果雜湊值和映像檔 ID 都相符,Compose 會保留現有容器,並顯示 Container voltest-db-1 Running,而不是 Recreated。這通常是您需要的行為,因為這讓 up -d 可以安全地重複執行。

這也是某些編輯看似沒有作用的原因。Compose 會計算解析後的服務定義,而不是該定義所指向之檔案的內容。掛載到容器中、並在啟動時讀取一次的設定檔,編輯後不會觸發重新建立,因為掛載路徑沒有變更。服務會繼續使用啟動時讀取的值執行。

docker compose up -d --force-recreate

此命令會停止並移除每個容器,然後根據相同的定義建立新容器。編輯掛載的設定檔後,以及容器偏離到無法解釋的狀態時,請使用此命令。此操作不會影響磁碟區,因此資料庫在強制重新建立後仍會保留。若要取得相同標籤下較新的映像檔,還需要同時執行 pull。

docker compose pull
docker compose up -d

pull 會取得新的映像檔 ID,接著 up -d 會發現該 ID 與執行中容器的 ID 不同,並自行重新建立容器。若加入 --force-recreate 但未加入 pull,您會從相同的舊映像檔建立新容器。因此,「我已強制重新建立,但版本仍然是舊的」會成為常見問題。

docker compose restart 不會執行上述任何操作。它只會重新啟動現有容器,完全不會重新讀取 Compose 檔案,因此變更的環境變數或連接埠對映不會套用。如果您編輯了該檔案,請使用 up -d

必須掌握的思維模型

容器可以替換。容器由程序和一個薄型可寫入層組成,而 Compose 約在 1 秒內即可根據檔案建立出完全相同的容器。磁碟區無法替換,因為其中保存的狀態只有一份,儲存庫中的檔案無法重新產生這些狀態。

每個 Compose 動詞都對應到這種區分。stopstart 會保留容器。downup 會替換容器並保留磁碟區。down -v 是唯一會移除狀態的例行命令,因此需要明確指定旗標。在任何實際環境中輸入此命令前,請先確認您有一份至少成功還原過 1 次的備份。

相同的邏輯也適用於秘密資料。透過 POSTGRES_PASSWORD 設定的密碼只會在資料庫首次初始化時讀取,因此在環境檔案中變更密碼後執行 up -d,會得到 password authentication failed for user "postgres"。容器是新的,但磁碟區是舊的,而舊磁碟區仍保存舊密碼。Compose 如何解析環境檔案與秘密資料 說明同一變數設定 2 次時,哪一層設定會生效。

失敗模式與您會看到的字串

no configuration file provided: not found 表示 Compose 在沒有 compose.yamldocker-compose.yml 的目錄中執行。請使用完整路徑傳入 -f

down 上的 network voltest_default has active endpoints 表示專案外部的容器已連接至專案網路。這通常是使用 docker run --network 手動啟動的容器。請移除該容器,然後再次執行 down

重新命名或刪除服務後會出現 Found orphan containers ([voltest-old-1]) for this project。舊容器仍保留專案標籤。docker compose down --remove-orphans 會清除這些容器,即使在堆疊運作正常時執行也安全。

手動執行 docker volume rm 時出現 Error response from daemon: remove voltest_pgdata: volume is in use,表示仍有容器參照該磁碟區,包括已停止的容器。請先執行 docker compose down,再移除磁碟區;或直接使用 down -v。在較大型的專案中,多服務 Compose 堆疊 說明單一專案可能累積多少磁碟區。

FAQ

docker compose down 會刪除我的資料庫嗎?

如果資料庫位於具名磁碟區或繫結掛載中,就不會。down 會移除容器和專案網路,但磁碟區及其中的資料會保留在磁碟上。下次執行 docker compose up -d 時,新的容器會連接至相同的磁碟區,資料也會存在。只有 docker compose down -v 會移除具名磁碟區,而且只會移除 Compose 檔案 volumes 區段中宣告的磁碟區。

對於想要稍後恢復的容器,stop 和 down 有何差異?

stop 會保留容器,因此 docker compose start 會讓您回到相同的容器,並保留相同的可寫入層。在容器內手動安裝或編輯的內容仍會存在。down 會刪除容器,因此下次執行 up -d 時,會從映像檔建立全新的容器,手動變更也會遺失。進行偵錯時,請使用 stop

如何移除 Compose 專案建立的所有內容?

docker compose down -v --rmi all --remove-orphans 會移除容器、專案網路、檔案中宣告的具名磁碟區、服務使用的映像檔,以及任何仍標記有專案名稱的容器。它不會處理繫結掛載或標記為 external: true 的磁碟區。執行前,請使用 docker volume ls 檢查即將遺失的內容。

為什麼我的容器會忽略對掛載組態檔所做的變更?

Compose 會比較解析後服務定義的雜湊值,以決定是否重新建立容器,而該雜湊值不包含掛載檔案的內容。檔案路徑沒有變更,因此 Compose 會讓容器繼續執行,並保留啟動時讀取的值。執行 docker compose up -d --force-recreate,建立會重新讀取該檔案的新容器。

為什麼變更後,新的 POSTGRES_PASSWORD 沒有生效?

Postgres 映像檔只會在初始化空白資料目錄時讀取 POSTGRES_PASSWORD。您的磁碟區已包含初始化完成的叢集,因此該變數會被忽略,舊密碼仍然有效。您會看到 password authentication failed for user "postgres"。請在執行中的資料庫內使用 ALTER USER 變更密碼;如果可以接受遺失資料,則使用 docker compose down -v 重新開始。