容器化技術 指令速查表
下一頁→
附錄

指令速查表

映像容器Compose網路儲存除錯清理Dockerfile 樣板

把整門課用到的指令收在一頁,按「你想做什麼」分類,而不是按指令字母排。每一組都附上它對應的原理章節,忘記為什麼要這樣下指令時可以直接回去看。

# === 拉取與查看 ===
docker pull nginx:1.25                     # 拉取(省略 tag 預設 latest)
docker images                              # 列出本機映像
docker history myapp:1.0                   # 每一層的來源指令與大小(ch03)
docker inspect myapp:1.0                   # 完整 metadata(CMD/ENV/USER…)

# === 建置 ===
docker build -t myapp:1.0 .                # 建置(. 是 build context,ch08)
docker build -f Dockerfile.prod -t myapp .  # 指定 Dockerfile
docker build --no-cache -t myapp:1.0 .     # 強制不用快取
docker build --build-arg JAR=x.jar .       # 傳入 ARG
docker build --platform linux/amd64 .      # 指定架構(M1 → x86,ch04)
docker build --progress=plain .            # 完整輸出(除錯建置用)

# === 多架構(buildx)===
docker buildx build --platform linux/amd64,linux/arm64 \
  -t myregistry.io/myapp:1.0 --push .

# === 標記與推送 ===
docker tag myapp:1.0 myharbor.com/team/myapp:1.0   # 名字就是位址(ch04)
docker login myharbor.com
docker push myharbor.com/team/myapp:1.0

# === 匯出入(無網路環境搬運)===
docker save myapp:1.0 | gzip > myapp.tar.gz
docker load < myapp.tar.gz

# === 安全 ===
docker scout cves myapp:1.0                # 漏洞掃描(ch10)
trivy image --severity HIGH,CRITICAL myapp:1.0
# === 執行 ===
docker run -d --name myapp -p 8080:8080 myapp:1.0    # 背景執行
docker run -it --rm ubuntu bash                       # 互動,結束即刪
docker run --rm -it --entrypoint sh myapp:1.0         # 繞過 entrypoint 除錯(ch13)

# 常用旗標(每個對應一章的原理)
#   -d 背景 | -it 互動 | --rm 結束即刪 | --name 取名
#   -p 宿主:容器(左外右內,ch07) | -e KEY=VAL 環境變數
#   -v 名稱:/路徑 volume(ch06) | -m 512m --cpus 1.5 資源(ch02)
#   --restart unless-stopped 重啟策略(ch05) | --init 塞 tini 當 PID 1(ch05)
#   -u 1000:1000 指定使用者(ch10) | --network 網路(ch07)

# === 查看 ===
docker ps                        # 執行中的
docker ps -a                     # 全部(含已結束)← 容器「不見了」的第一站
docker logs -f --tail 100 myapp  # 日誌(其實是 PID 1 的 stdout,ch05)
docker logs --since 10m myapp
docker top myapp                 # 容器內的 process → 驗證誰是 PID 1
docker stats                     # 即時資源用量(已用 / cgroup 上限)
docker diff myapp                # 相對映像改了哪些檔案(可寫層,ch03)

# === 進入與傳檔 ===
docker exec -it myapp bash            # 開新 shell(不影響 PID 1)✅
docker exec -u root -it myapp bash    # 以 root 進去除錯
docker cp myapp:/tmp/heap.hprof ./    # 撈檔案出來
docker cp ./config.yml myapp:/app/    # 送檔案進去

# === 停止與刪除 ===
docker stop myapp                # SIGTERM → 等 10 秒 → SIGKILL(ch05)
docker stop --time=30 myapp      # 拉長寬限期(Java 優雅關機用)
docker kill myapp                # 直接 SIGKILL(卡死時才用)
docker restart myapp
docker rm myapp                  # 刪除(可寫層一併消失,ch03)
docker rm -f myapp               # kill + rm
# === 啟動與停止 ===
docker compose up -d                     # 背景啟動全部
docker compose up -d --build             # 重新建置後啟動
docker compose up -d --build --no-deps app   # ⭐只重建 app,不動資料庫
docker compose --profile tools up -d     # 含 profile 標記的服務(ch11)
docker compose stop                      # 只停止,容器保留
docker compose down                      # 移除容器與網路(volume 保留 ✅)
docker compose down -v                   # 💣 連 volume 一起刪,資料全毀

# === 查看與進入 ===
docker compose ps                        # 狀態(含 healthy 與否)
docker compose ps -a                     # 含已結束(看一次性任務有沒有成功)
docker compose logs -f app               # 跟隨單一服務
docker compose logs -f --tail 100        # 全部服務最近 100 行
docker compose exec app bash
docker compose top                       # 各容器內的 process

# === 排查(最重要的一個)===
docker compose config                    # ⭐變數展開+多檔合併後的最終設定
docker compose config --services         # 列出所有服務名

# === 多檔與專案 ===
docker compose -f base.yml -f prod.yml up -d    # 後面覆蓋前面(ch11)
docker compose -p myproject up -d               # 指定專案名(不依賴目錄名)

# === 直接操作服務 ===
docker compose restart app               # 重啟(不重建,改程式碼不會生效)
docker compose rm -f sqlserver           # 刪掉單一服務的容器
docker compose pull                      # 更新所有映像
docker compose run --rm app mvn test     # 跑一次性指令(不影響現有容器)
# === 網路(ch07)===
docker network ls
docker network create my-net
docker network inspect my-net             # 看有哪些容器在裡面
docker network connect my-net myapp       # 把既有容器加進網路
docker network disconnect my-net myapp

# 網路診斷(精簡映像沒工具時的救星)
docker run --rm -it --network my-net nicolaka/netshoot bash
docker run --rm -it --network container:myapp nicolaka/netshoot bash  # ⭐共用目標的網路視角

# 容器內測試
docker compose exec app getent hosts sqlserver   # DNS 解析
docker compose exec app nc -zv sqlserver 1433    # 連通性
docker compose exec sqlserver ss -lntp           # 監聽在 0.0.0.0 還是 127.0.0.1?

# === Volume(ch06)===
docker volume ls
docker volume ls -f dangling=true         # 沒人用的(常是匿名 volume 垃圾)
docker volume inspect mssql-data          # 看它在宿主機的實際路徑
docker volume create my-data
docker volume rm my-data

# 備份 / 還原 volume(通用技巧)
docker run --rm -v mssql-data:/source:ro -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

docker run --rm -v mssql-data:/target -v $(pwd):/backup \
  alpine sh -c 'cd /target && tar xzf /backup/backup.tar.gz'

# 確認容器實際掛了什麼(「改了沒生效」第一站)
docker inspect myapp --format '{{json .Mounts}}' | jq
# === 狀態與死因(ch13)===
docker inspect myapp --format '{{.State.Status}} exit={{.State.ExitCode}} oom={{.State.OOMKilled}}'
docker inspect myapp --format '{{json .State.Health}}' | jq    # 健康檢查歷史
docker inspect myapp --format '{{json .Config.Env}}' | jq      # 實際生效的環境變數
docker inspect myapp --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'

# === 事件時間序(間歇性問題的利器)===
docker events --since 12h
docker events --since 1h --filter 'container=myapp'

# === Exit Code 速記(ch13)===
#  0   正常結束(預期常駐卻拿到 → 主程式不是前景)
#  1   應用自己的錯誤 → 看 logs
#  125 Docker 指令本身錯誤   126 找到但不能執行(權限/CRLF)
#  127 指令不存在(distroless 沒 bash)
#  137 SIGKILL(多半是 OOMKilled)   139 Segfault(架構/JNI)
#  143 SIGTERM 正常結束 ← 好消息,優雅關機生效

# === 磁碟清理(先看再清!)===
docker system df                 # ⭐誰在吃空間
docker system df -v              # 逐項明細
docker system prune              # 停止的容器、無用網路、懸空映像
docker system prune -a           # 連沒有容器在用的映像也清
docker builder prune             # 建置快取(常有數十 GB)
docker image prune -a
docker container prune
docker system prune --volumes    # 💣 會刪 volume 資料,當危險品對待

Dockerfile(多階段 + 非 root + 快取最佳化)

# syntax=docker/dockerfile:1
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /build
COPY pom.xml .
RUN --mount=type=cache,target=/root/.m2 mvn dependency:go-offline -B
COPY src ./src
RUN --mount=type=cache,target=/root/.m2 mvn clean package -DskipTests -B

FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
RUN groupadd -r spring && useradd -r -g spring spring
COPY --from=builder --chown=spring:spring /build/target/*.jar app.jar
USER spring
EXPOSE 8080
ENV TZ=Asia/Taipei
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD wget -qO- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "/app/app.jar"]

.dockerignore

target/
build/
node_modules/
.git/
.idea/
.vscode/
.env
*.pem
*.key
Dockerfile
docker-compose*.yml
README.md

compose 骨架

name: myapp
services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: 'Y'
      MSSQL_SA_PASSWORD: ${MSSQL_SA_PASSWORD:?請設定}
    ports: ['127.0.0.1:1433:1433']
    volumes: ['mssql-data:/var/opt/mssql']
    healthcheck:
      test: ['CMD-SHELL', '/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -C -Q "SELECT 1" || exit 1']
      interval: 10s
      retries: 12
      start_period: 30s

  app:
    build: .
    ports: ['8080:8080']
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:sqlserver://sqlserver:1433;databaseName=mydb;encrypt=true;trustServerCertificate=true'
      SPRING_DATASOURCE_PASSWORD: ${MSSQL_SA_PASSWORD}
    depends_on:
      sqlserver: { condition: service_healthy }

volumes:
  mssql-data:
我想做 X」→ 該下哪個指令
我想…指令章節
看容器為什麼不見了docker ps -a → docker logsch05/ch13
確認我的程式是不是 PID 1docker top &lt;容器&gt;ch05
確認是不是被 OOM 殺的docker inspect --format '{{.State.OOMKilled}}'ch02/ch09
看設定到底有沒有生效docker compose configch11
只重建 app 不動資料庫docker compose up -d --build --no-deps appch12
容器起不來、來不及 execdocker run --rm -it --entrypoint sh &lt;映像&gt;ch13
診斷 distroless 的網路docker run --rm -it --network container:&lt;目標&gt; nicolaka/netshoot bashch13
查磁碟被什麼吃光docker system df -vch05
看映像每層多大docker history &lt;映像&gt; 或 divech03/ch10
追查半夜自己重啟docker events --since 12hch13

練習題 點選選項查看解析

0 / 4
01 / 4
要「只重新建置並重啟 app,不動正在跑的資料庫」,正確指令是?
A docker compose restart app
B docker compose up -d --build --no-deps app
C docker compose down && docker compose up -d
D docker compose rebuild app
解析
--no-deps 表示不連帶處理相依服務。注意 restart 不會重新建置映像——改了程式碼用 restart 是不會生效的,這是很常見的誤用。
02 / 4
容器一啟動就死掉,來不及 docker exec 進去看。最有效的指令是?
A docker logs -f
B docker run --rm -it --entrypoint sh myapp:1.0,繞過 entrypoint 直接取得 shell,再手動執行啟動指令
C docker restart
D docker inspect
解析
進去之後可以逐步驗證:ls 看檔案在不在、whoami 看身分、env 看環境變數、手動跑啟動指令看完整錯誤輸出。
03 / 4
下列哪個清理指令會刪掉你的資料庫資料?
A docker system prune
B docker system prune --volumes
C docker builder prune
D docker image prune -a
解析
--volumes 會刪掉沒被容器使用的 volume。volume 在容器刪除後被保留是刻意的保護,這個旗標正好把保護拆掉。安全流程:先 docker system df 看清楚誰在吃空間再決定。
04 / 4
要驗證「我的 Java 程式到底是不是容器裡的 PID 1」,用哪個指令?
A docker stats
B docker top <容器>
C docker inspect
D docker events
解析
docker top 列出容器內的 process 清單。如果看到 /bin/sh -c java -jar... 而 java 是它的子行程,代表你用了 shell form,SIGTERM 收不到、優雅關機會失效(ch05)。

點擊卡片翻面查看答案,共 5 張。

QUESTION
最常用的三個排查指令?
點擊翻面
ANSWER
docker compose ps -a(誰活著)
docker compose logs --tail 100(它怎麼說)
docker compose config(設定實際長怎樣)
點擊翻回
QUESTION
開發時最省時間的一個指令?
點擊翻面
ANSWER
docker compose up -d --build --no-deps app
只重建重啟 app,不重啟要等 30~60 秒的資料庫
點擊翻回
QUESTION
容器起不來的萬用救命招?
點擊翻面
ANSWER
docker run --rm -it --entrypoint sh myapp:1.0
繞過 entrypoint 進去手動驗證
(ls / whoami / env / 手動跑啟動指令)
點擊翻回
QUESTION
精簡映像沒工具時怎麼診斷網路?
點擊翻面
ANSWER
docker run --rm -it --network container:<目標> nicolaka/netshoot bash
共用目標容器的 network namespace → 網路視角完全一樣
點擊翻回
QUESTION
磁碟滿了的安全清理流程?
點擊翻面
ANSWER
① docker system df -v(先看誰在吃)
② docker system prune(容器/網路/懸空映像)
③ docker builder prune(建置快取)
⚠️ --volumes 會刪資料,當危險品
點擊翻回