目錄
docker compose 常用指令大全
所有 docker compose 指令都要在 compose.yaml 所在的資料夾(或子資料夾)執行,或用 -f 指定檔案。指令後面可以接服務名稱,只對該服務操作;不接就是整個專案。本節的例子都使用 Compose 入門 中的 compose-demo 專案。
啟動與停止
| 指令 | 作用 |
|---|---|
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)。
| exec | run | |
|---|---|---|
| 容器 | 使用已在執行的容器 | 建立新容器 |
| 服務需要先啟動嗎 | 是 | 否 |
套用 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 或 .env | docker compose up -d |
| 改了 Dockerfile 或套件清單 | docker compose up -d --build |
| 看某個服務為什麼掛掉 | docker compose logs app |
| 進資料庫下 SQL | docker 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日