目錄

docker run 參數完整說明(附實際執行結果)

docker run 是最常用、參數也最多的 Docker 指令。基本格式是:

docker run [參數] 映像檔[:tag] [指令] [指令的參數]

映像檔名稱之後的部分會取代映像檔預設的指令(CMD):

$ docker run --rm alpine:3.23 cat /etc/alpine-release
3.23.6

--rm 是給 Docker 的參數;cat /etc/alpine-release 則是在容器裡執行的指令,它取代了 alpine 預設的 /bin/sh。

參數一定要寫在映像檔名稱之前

寫在映像檔名稱後面的東西,全部會被當成容器內的指令:

$ docker run alpine:3.23 --rm echo hi
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "--rm": executable file not found in $PATH

Run 'docker run --help' for more information

Docker 試圖在容器裡執行一個叫 --rm 的程式,當然找不到(executable file not found)。看到這種錯誤,先檢查參數的位置。

執行模式

參數說明
-d, --detach在背景執行,印出容器 ID 後立即返回
-i, --interactive保持標準輸入開啟
-t, --tty配置一個虛擬終端機
--rm容器結束後自動刪除
--name指定容器名稱,否則會隨機產生(例如 dreamy_solomon)
docker run -it --rm ubuntu:26.04 bash      # 互動式進入,離開後自動刪除
docker run -d --name cache redis:8-alpine  # 背景服務

-it 幾乎總是一起使用,用來進入互動式的 shell。只用 -i 則可以把資料用管線送進容器:

$ echo "hello" | docker run -i --rm alpine:3.23 cat
hello

連接埠:-p

格式是 -p 主機連接埠:容器連接埠。下面三種寫法實際對照:

$ docker run -d --name p1 -p 8080:80 nginx:1.30
27b89a4fae92dfe05bf051e11700033c7b9bb71f8747acc986d2a535cc1baa00

$ docker run -d --name p2 -p 127.0.0.1:8081:80 nginx:1.30
3327f3c1df4fa1e03fa3a120e5d889859fc0cb53d0aaf269826c81b25f4411c2

$ docker run -d --name p3 -P nginx:1.30
57c9a309c4758786361738b7b9a4231f404cb9bbab28f38cad39b4b6e996d9e0

$ docker port p1
80/tcp -> 0.0.0.0:8080
80/tcp -> [::]:8080

$ docker port p2
80/tcp -> 127.0.0.1:8081

$ docker port p3
80/tcp -> 0.0.0.0:32768
80/tcp -> [::]:32768
寫法結果
-p 8080:80綁定所有網路介面(0.0.0.0 與 IPv6 的 [::]),其他電腦也能連
-p 127.0.0.1:8081:80只綁定本機,只有這台電腦自己能連
-P把映像檔 EXPOSE 的連接埠對應到隨機的主機連接埠(這次分到 32768)

docker port 容器名稱 可以查看實際的對應。UDP 連接埠要寫成 -p 5353:53/udp。

-p 8080:80 在雲端主機上代表外部可以直接連到;而且 Docker 會自己改寫防火牆規則,ufw 的設定可能擋不住。資料庫等不該對外的服務,請綁定 127.0.0.1,或乾脆不要用 -p,改用 自訂網路 讓容器互連。

資料:-v 與 --mount

-v 主機路徑:容器路徑 把主機上的資料夾掛進容器(bind mount)。準備一個 site 資料夾,裡面有一個 index.html:

$ ls site
index.html

$ docker run -d --name site -p 8080:80 -v "$(pwd)/site:/usr/share/nginx/html:ro" nginx:1.30
e91f46b91ff8f0f64d59d6605bfddea0ee5bca809de86d81cbd5051815e65dd1

$ curl -s http://localhost:8080 | head -n 3
<!doctype html>
<html><head><meta charset="utf-8"><title>My site</title>
<style>body{font-family:system-ui,sans-serif;max-width:640px;margin:60px auto;padding:0 16px;color:#1f2937}h1{color:#1d63ed}</style></head>

對應 Windows 的寫法(點選分頁切換):

docker run -d --name site -p 8080:80 -v "$(pwd)/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d --name site -p 8080:80 -v "${PWD}/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d --name site -p 8080:80 -v "%cd%/site:/usr/share/nginx/html:ro" nginx:1.30
nginx 顯示 bind mount 進來的網頁
nginx 顯示的是主機上 site/index.html 的內容

結尾的 :ro 代表唯讀。容器裡想寫入這個資料夾會被拒絕:

$ docker exec site sh -c "echo test > /usr/share/nginx/html/x.txt"
sh: 1: cannot create /usr/share/nginx/html/x.txt: Read-only file system

另一種掛載方式是使用 Docker 管理的 Volume(-v 名稱:容器路徑),適合保存資料庫等資料:

docker run -d -v pgdata:/var/lib/postgresql postgres:18

--mount 是寫法較長但更明確的版本,兩者的差異和使用時機請看 Volume 與 Bind Mount。

環境變數:-e 與 --env-file

$ docker run --rm -e GREETING=hello -e APP_ENV=dev alpine:3.23 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=18f035817c43
GREETING=hello
APP_ENV=dev
HOME=/root

-e 變數名稱(不寫值)會沿用主機目前的同名環境變數:

$ APP_ENV=prod docker run --rm -e APP_ENV alpine:3.23 sh -c 'echo $APP_ENV'
prod

變數很多時改用 --env-file 檔案,詳見 環境變數與 .env 檔。

網路

在同一個自訂網路中的容器,可以用容器名稱互相連線:

$ docker network create mynet
2ecd542737519b0b8919061077814e007a72e2d07973f0840608b1b5454c678e

$ docker run -d --name myweb --network mynet nginx:1.30
9a6ca3dca3a003e28b9870f3eec436cf7023a6872e8ddd4cee971d29f845583b

$ docker run --rm --network mynet alpine:3.23 ping -c 2 myweb
PING myweb (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.094 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.064 ms

--- myweb ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.064/0.079/0.094 ms

$ docker run --rm alpine:3.23 ping -c 1 -W 2 myweb
ping: bad address 'myweb'
  • 第一個 ping 容器在 mynet 裡,myweb 被 Docker 內建的 DNS 解析成 172.19.0.2。
  • 第二個沒有加 --network,在預設網路裡,找不到 myweb(bad address)。

容器名稱避免取成 web、app 這類剛好是頂級網域(TLD)的單字。在沒有加入同一網路時,這種名稱會被外部 DNS 解析到奇怪的位址(例如 127.0.53.53),讓除錯更困惑。

docker run --network host nginx:1.30     # 直接使用主機網路(Linux)
docker run --network none alpine:3.23    # 完全沒有網路

詳見 網路與容器互連。

重啟策略

docker run -d --restart unless-stopped nginx:1.30

可用值有 no、on-failure、always、unless-stopped,實際行為見 容器生命週期。

資源限制

$ docker run -d --name limited --memory 64m --cpus 0.5 nginx:1.30
2e65ce89f346cb7d9d57f1e6ad529d63ad53d1d914b6d3178dc3344a1d3325f0

$ docker stats --no-stream limited
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O         PIDS
2e65ce89f346   limited   0.00%     3.922MiB / 64MiB    6.13%     736B / 126B   1.77MB / 8.19kB   2

MEM USAGE / LIMIT 顯示 3.922MiB / 64MiB,記憶體上限生效了。nginx 閒置時只用了不到 4 MB。

參數說明
--memory, -m記憶體上限,例如 512m、2g;超過時程序會被終止(OOM,結束代碼 137)
--memory-swap記憶體 + swap 的總上限
--cpus可使用的 CPU 數量,可以是小數,0.5 代表半顆
--pids-limit容器內最多的程序數

記憶體超過上限時的實際情況,見 查看日誌與除錯 中的 OOM 範例。

覆蓋映像檔的預設值

$ docker run --rm --entrypoint sh nginx:1.30 -c "nginx -v; whoami"
nginx version: nginx/1.30.5
root

$ docker run --rm -u 1000:1000 alpine:3.23 id
uid=1000 gid=1000 groups=1000

$ docker run --rm -w /tmp alpine:3.23 pwd
/tmp

$ docker run --rm -h myhost alpine:3.23 hostname
myhost
參數說明
--entrypoint覆蓋 ENTRYPOINT,常用來進入原本會直接啟動服務的映像檔裡看看
-u, --user以指定的使用者(UID:GID)執行
-w, --workdir覆蓋工作目錄
-h, --hostname容器的主機名稱

-u 常用來讓容器產生的檔案屬於你自己,而不是 root:

docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd):/work" -w /work node:24-alpine npm install

唯讀檔案系統

$ docker run --rm --read-only alpine:3.23 touch /hello
touch: /hello: Read-only file system

--read-only 讓整個容器的檔案系統唯讀,就算程式被入侵也無法修改檔案。需要寫入的地方再用 --tmpfs /tmp 或 Volume 開放,見 安全最佳實務。

其他實用參數

參數說明
--init用小型 init 程序當 PID 1,正確轉發訊號(docker stop 不用等 10 秒,見 容器生命週期)
--platform指定平台,例如 linux/amd64
--add-host加一筆 hosts 記錄,例如 --add-host host.docker.internal:host-gateway
--label加上標籤,方便篩選
--pull always每次執行前都重新拉取映像檔
--log-opt max-size=10m限制日誌檔大小

更多參數速查

以下依 docker run --help(Docker 29)整理本章沒有詳細介紹、但實用的參數。完整清單請執行 docker run --help。

分類參數說明
安全--cap-add / --cap-drop增加或移除 Linux capabilities,實測見 安全最佳實務
安全--security-opt安全選項,例如 no-new-privileges、seccomp 設定
安全--privileged給容器所有權限,幾乎關閉隔離,避免使用
安全--userns使用的 user namespace
健康檢查--health-cmd健康檢查指令,例如 --health-cmd "curl -f http://localhost/"
健康檢查--health-interval / --health-timeout / --health-retries檢查間隔、逾時、連續失敗幾次才算 unhealthy
健康檢查--health-start-period / --health-start-interval啟動期間的寬限時間與檢查間隔
健康檢查--no-healthcheck停用映像檔中設定的 HEALTHCHECK
網路--network-alias在網路中多一個名稱,見 docker network
網路--ip在自訂網路中指定固定 IP
網路--dns / --dns-search自訂 DNS 伺服器與搜尋網域
網路--expose宣告連接埠(不對應到主機),效果同 Dockerfile 的 EXPOSE
網路-P, --publish-all把所有宣告的連接埠對應到隨機的主機連接埠
停止--stop-signaldocker stop 送出的訊號,預設 SIGTERM
停止--stop-timeoutdocker stop 等待的秒數,預設 10
資源--cpuset-cpus只使用指定的 CPU,例如 0,1 或 0-3
資源-c, --cpu-sharesCPU 相對權重(資源競爭時才有作用)
資源--memory-reservation記憶體軟上限
資源--shm-size/dev/shm 的大小,PostgreSQL、瀏覽器等程式常需要調大
資源--ulimit例如 --ulimit nofile=65535:65535 調整開啟檔案數上限
資源--oom-kill-disable停用記憶體不足時的強制終止(要搭配 --memory)
裝置--device把主機裝置交給容器,例如 /dev/ttyUSB0
裝置--gpus使用 GPU,例如 --gpus all(需要 NVIDIA Container Toolkit)
命名空間--pid host / --ipc / --uts共用主機或其他容器的命名空間,原理見 底層原理
系統--sysctl設定容器的核心參數,例如 net.core.somaxconn=1024
系統--umask容器中程序的 umask
掛載--volumes-from掛載另一個容器的所有 Volume
其他--cidfile把容器 ID 寫進檔案,方便腳本使用
其他--label-file從檔案讀取標籤
其他--log-driver日誌驅動程式,例如 json-file、local、syslog
其他-q, --quiet下載映像檔時不顯示進度
其他--use-api-socket把 Docker API socket 與登入憑證掛進容器(等同主機 root 權限,見 安全最佳實務)

常見組合範例

# 1. 一次性的工具容器:在目前資料夾執行指令
docker run --rm -v "$(pwd):/data" -w /data alpine:3.23 ls -la

# 2. 本機開發用資料庫,只開放本機連線
docker run -d --name devdb --restart unless-stopped \
  -p 127.0.0.1:5432:5432 \
  -e POSTGRES_PASSWORD=dev \
  -v devdb:/var/lib/postgresql \
  postgres:18

# 3. 正式服務,限制資源與日誌大小
docker run -d --name api --restart unless-stopped \
  --memory 1g --cpus 2 \
  --log-opt max-size=10m --log-opt max-file=3 \
  --env-file .env -p 3000:3000 \
  myorg/api:1.4.2
# 1. 一次性的工具容器:在目前資料夾執行指令
docker run --rm -v "${PWD}:/data" -w /data alpine:3.23 ls -la

# 2. 本機開發用資料庫,只開放本機連線
docker run -d --name devdb --restart unless-stopped `
  -p 127.0.0.1:5432:5432 `
  -e POSTGRES_PASSWORD=dev `
  -v devdb:/var/lib/postgresql `
  postgres:18

# 3. 正式服務,限制資源與日誌大小
docker run -d --name api --restart unless-stopped `
  --memory 1g --cpus 2 `
  --log-opt max-size=10m --log-opt max-file=3 `
  --env-file .env -p 3000:3000 `
  myorg/api:1.4.2
# 1. 一次性的工具容器:在目前資料夾執行指令
docker run --rm -v "%cd%:/data" -w /data alpine:3.23 ls -la

# 2. 本機開發用資料庫,只開放本機連線
docker run -d --name devdb --restart unless-stopped ^
  -p 127.0.0.1:5432:5432 ^
  -e POSTGRES_PASSWORD=dev ^
  -v devdb:/var/lib/postgresql ^
  postgres:18

# 3. 正式服務,限制資源與日誌大小
docker run -d --name api --restart unless-stopped ^
  --memory 1g --cpus 2 ^
  --log-opt max-size=10m --log-opt max-file=3 ^
  --env-file .env -p 3000:3000 ^
  myorg/api:1.4.2

參數一多,指令就很難維護。需要長期執行或多個容器一起運作時,建議改用 Docker Compose 把設定寫進檔案裡。

重點回顧

  • 參數寫在映像檔名稱之前,之後的內容是容器內要執行的指令。
  • -d、--rm、--name、-p、-v、-e 是最常用的組合。
  • --memory、--cpus、--pids-limit 限制資源。
  • --entrypoint、-u、-w 覆蓋映像檔的預設值。

動手練習

練習 1:寫出一個指令:在背景執行 nginx:1.30-alpine,名稱 site,只讓本機的 8080 埠連得到,記憶體上限 128 MB,結束後不保留容器。

答案
docker run -d --rm --name site -p 127.0.0.1:8080:80 --memory 128m nginx:1.30-alpine

--rm 讓容器停止後自動刪除。

練習 2:postgres:18 映像檔的 ENTRYPOINT 會啟動資料庫。怎麼只進入它的 shell 看看,而不啟動資料庫?

答案
docker run --rm -it --entrypoint sh postgres:18

--entrypoint 覆蓋映像檔的 ENTRYPOINT。

常見問題

參數寫在映像檔名稱後面為什麼沒有作用?

映像檔名稱之後的內容會被當成要在容器內執行的指令。docker run 的參數一定要寫在映像檔名稱之前。

-p 8080:80 和 -p 127.0.0.1:8080:80 有什麼不同?

前者綁定所有網路介面,其他電腦也能連;後者只綁定本機。資料庫等不需要對外的服務,請用後者或完全不加 -p。

docker run 有多少個參數?

Docker 29 的 docker run --help 列出約 100 個參數。本章介紹最常用的,最後的「更多參數速查」整理了其他實用的參數。

更新於 2026年10月14日