目錄

docker compose 常用指令大全

所有 docker compose 指令都要在 compose.yaml 所在的資料夾(或子資料夾)執行,或用 -f 指定檔案。指令後面可以接服務名稱,只對該服務操作;不接就是整個專案。本節的例子都使用 Compose 入門 中的 compose-demo 專案。

docker compose 的 up、stop、start、down 如何改變服務狀態,以及 restart、up -d、down -v 的差別
Compose 指令與服務狀態的關係

啟動與停止

指令作用
docker compose up建立並啟動,日誌輸出在前景,Ctrl+C 停止
docker compose up -d在背景啟動
docker compose up -d --build先重新建置映像檔再啟動
docker compose up -d app只啟動 app(以及它依賴的服務)
docker compose up -d --force-recreate即使設定沒變也重建容器
docker compose up -d --remove-orphans刪除設定檔中已經不存在的服務的容器
docker compose stop停止,容器保留
docker compose start啟動已停止的容器
docker compose restart app重啟服務(不會套用新的設定,見下方實測)
docker compose down停止並刪除容器、網路
docker compose down -v同時刪除 Volume(資料會消失)
docker compose down --rmi local同時刪除 Compose 建置的映像檔

up、stop、start、down 的實際輸出見 Compose 入門。

查看狀態

$ docker compose ps
NAME                     IMAGE               COMMAND                  SERVICE   CREATED          STATUS         PORTS
compose-demo-adminer-1   adminer             "entrypoint.sh docke…"   adminer   10 seconds ago   Up 9 seconds   0.0.0.0:8081->8080/tcp, [::]:8081->8080/tcp
compose-demo-db-1        postgres:18         "docker-entrypoint.s…"   db        10 seconds ago   Up 9 seconds   5432/tcp
compose-demo-web-1       nginx:1.30-alpine   "/docker-entrypoint.…"   web       10 seconds ago   Up 8 seconds   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp

$ docker compose ls
NAME                STATUS              CONFIG FILES
compose-demo        running(3)          /work/compose-demo/compose.yaml

$ docker compose images
CONTAINER                REPOSITORY          TAG                 PLATFORM            IMAGE ID            SIZE                CREATED
compose-demo-adminer-1   adminer             latest              linux/amd64         74f29c416e14        164MB               2 weeks ago
compose-demo-db-1        postgres            18                  linux/amd64         74935e722416        644MB               6 days ago
compose-demo-web-1       nginx               1.30-alpine         linux/amd64         0985e772fb9f        92.8MB              2 weeks ago

$ docker compose top web
SERVICE  #   PID    USER  TIME  COMMAND
web      1   21356  root  0:00  nginx: master process nginx -g daemon off;
web      1   21425  101   0:00  nginx: worker process
指令內容
docker compose ps這個專案的容器與狀態(-a 包含已停止的)
docker compose ls這台機器上所有 Compose 專案,以及它們的設定檔位置
docker compose images每個容器使用的映像檔、平台與大小
docker compose top web服務容器內的程序

查看日誌

$ docker compose logs --tail 2 -t web
web-1  | 2026-10-13T00:18:19.618825771Z 2026/10/13 00:18:19 [notice] 1#1: start worker processes
web-1  | 2026-10-13T00:18:19.619080382Z 2026/10/13 00:18:19 [notice] 1#1: start worker process 30
docker compose logs               # 所有服務
docker compose logs -f app        # 持續追蹤 app
docker compose logs --tail 50 -t  # 最後 50 行,加上時間

在服務中執行指令

exec:在執行中的容器裡

$ docker compose exec web nginx -v
nginx version: nginx/1.30.5

$ docker compose exec db psql -U postgres -c "SELECT now();"
              now
-------------------------------
 2026-10-13 00:18:28.618314+00
(1 row)


$ docker compose exec -T db pg_dump -U postgres postgres > backup.sql && wc -l backup.sql
27 backup.sql

$ rm backup.sql
  • 用服務名稱(web、db)指定容器,不用管實際的容器名稱。
  • -T 停用虛擬終端機。把輸出導向檔案(例如上面的 pg_dump > backup.sql)或在腳本中使用時一定要加,否則輸出可能混入終端機控制字元。
  • docker compose exec web sh 開一個互動 shell。

run:開一個新的一次性容器

$ docker compose run --rm web nginx -t
Container compose-demo-web-run-80040d25219f Creating
Container compose-demo-web-run-80040d25219f Created
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

run 會用服務的設定(映像檔、環境變數、Volume、網路)建立一個新容器來執行指令(名稱是 compose-demo-web-run-…),--rm 讓它結束後自動刪除。上面用它在不影響執行中服務的情況下檢查 nginx 設定(nginx -t)。

execrun
容器使用已在執行的容器建立新容器
服務需要先啟動嗎是否
套用 ports 嗎—預設不會,需要時加 --service-ports
適合進去除錯、在執行中的服務裡操作跑測試、資料庫遷移等一次性任務

修改設定後:restart 不夠,要 up -d

這是最常見的誤解。實驗:在 compose.yaml 的 web 服務加上一個環境變數 SITE_TITLE: v2,然後分別試試 restart 和 up -d:

$ docker compose --progress plain restart web
 Container compose-demo-web-1 Restarting
 Container compose-demo-web-1 Started

$ docker compose exec web sh -c "echo SITE_TITLE=\$SITE_TITLE"
SITE_TITLE=

$ docker compose up -d
[+] up 3/3
 ✔ Container compose-demo-db-1      Running                                                     0.0s
 ✔ Container compose-demo-adminer-1 Running                                                     0.0s
 ✔ Container compose-demo-web-1     Started                                                     0.4s

$ docker compose exec web sh -c "echo SITE_TITLE=\$SITE_TITLE"
SITE_TITLE=v2
  • restart 只是把現有的容器停止再啟動,容器的設定是建立時就決定的,所以看不到新的環境變數(SITE_TITLE= 是空的)。
  • up -d 會比對 compose.yaml 和現有容器,發現 web 的設定變了,就重建 web(Started),沒變的 db、adminer 維持原狀(Running)。

修改了 compose.yaml 或 .env 之後,一律用 docker compose up -d。

建置與映像檔

docker compose build              # 建置所有有 build 設定的服務
docker compose build --no-cache app
docker compose pull               # 下載所有服務的最新映像檔
docker compose push               # 推送有 image 名稱的服務
$ docker compose pull
[+] pull 3/3
 ✔ Image adminer           Pulled                                                               0.7s
 ✔ Image nginx:1.30-alpine Pulled                                                               0.5s
 ✔ Image postgres:18       Pulled                                                               1.3s

更新使用現成映像檔的服務,常見流程:

docker compose pull
docker compose up -d
docker image prune -f   # 清除被取代的舊版映像檔

檢查設定

$ docker compose config --services
db
adminer
web

$ docker compose config --volumes
pgdata

$ docker compose port web 80
0.0.0.0:8080
docker compose config             # 顯示合併、變數替換後的完整設定
docker compose config --services  # 列出所有服務名稱
docker compose config --volumes   # 列出 Volume
docker compose port web 80        # 服務的某個容器連接埠對應到主機的哪裡

docker compose config 的完整輸出範例見 compose.yaml 語法。

其他

docker compose cp web:/etc/nginx/nginx.conf ./nginx.conf   # 複製檔案
docker compose watch                                       # 開發時偵測檔案變更自動同步或重建
docker compose up -d --scale worker=3                      # 啟動 3 個 worker

全域參數

這些參數寫在 docker compose 和子指令之間:

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose -p myproject up -d          # 指定專案名稱
docker compose --env-file .env.prod up -d  # 指定 .env 檔
docker compose --profile tools up -d       # 啟用 profile
docker compose --progress plain up -d      # 純文字進度輸出(適合 CI 記錄)

日常情境整理

我想要…指令
開始一天的開發docker compose up -d
改了 compose.yaml 或 .envdocker compose up -d
改了 Dockerfile 或套件清單docker compose up -d --build
看某個服務為什麼掛掉docker compose logs app
進資料庫下 SQLdocker compose exec db psql -U postgres
跑一次資料庫遷移docker compose run --rm app <遷移指令>
收工docker compose stop 或 down
完全重來(含資料)docker compose down -v

重點回顧

  • 修改 compose.yaml 或 .env 後,一律用 docker compose up -d。
  • exec 用在執行中的容器,run --rm 開一次性容器。
  • docker compose config 檢查合併後的最終設定。
  • up 與 down 的完整參數見 docker compose up 與 docker compose down。

動手練習

練習 1:修改 compose.yaml 中 web 的主機連接埠後,用 docker compose restart web 和 docker compose up -d 分別試試,哪一個會套用新的連接埠?

答案

只有 up -d 會。restart 重啟的是原本的容器,連接埠設定在容器建立時就決定了。

練習 2:用一個一次性容器在 db 服務的網路中執行 psql --version,結束後自動刪除容器。

答案
docker compose run --rm db psql --version

常見問題

docker compose restart 和 up -d 差在哪?

restart 只是重新啟動同樣的容器,compose.yaml 與 .env 的修改不會套用;up -d 會比對設定並重建有變動的服務。

docker compose exec 和 run 該用哪個?

exec 在已經執行的容器中執行指令;run 啟動一個新的一次性容器,適合資料庫遷移等工作,加 --rm 用完即刪。

怎麼看所有 Compose 專案?

docker compose ls 列出這台機器上所有的 Compose 專案與設定檔位置。

更新於 2026年10月14日