把整門課用到的指令收在一頁,按「你想做什麼」分類,而不是按指令字母排。每一組都附上它對應的原理章節,忘記為什麼要這樣下指令時可以直接回去看。
# === 拉取與查看 ===
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 資料,當危險品對待# 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"]target/
build/
node_modules/
.git/
.idea/
.vscode/
.env
*.pem
*.key
Dockerfile
docker-compose*.yml
README.mdname: 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:| 我想… | 指令 | 章節 |
|---|---|---|
| 看容器為什麼不見了 | docker ps -a → docker logs | ch05/ch13 |
| 確認我的程式是不是 PID 1 | docker top <容器> | ch05 |
| 確認是不是被 OOM 殺的 | docker inspect --format '{{.State.OOMKilled}}' | ch02/ch09 |
| 看設定到底有沒有生效 | docker compose config | ch11 |
| 只重建 app 不動資料庫 | docker compose up -d --build --no-deps app | ch12 |
| 容器起不來、來不及 exec | docker run --rm -it --entrypoint sh <映像> | ch13 |
| 診斷 distroless 的網路 | docker run --rm -it --network container:<目標> nicolaka/netshoot bash | ch13 |
| 查磁碟被什麼吃光 | docker system df -v | ch05 |
| 看映像每層多大 | docker history <映像> 或 dive | ch03/ch10 |
| 追查半夜自己重啟 | docker events --since 12h | ch13 |
點擊卡片翻面查看答案,共 5 張。