mcpField
D
docker-dockerfile

docker-dockerfile

github.com/full-stack-skillsクラウド・DevOps3125 回インストール4 週間前に更新
リポジトリ

docker-dockerfile について

アプリケーションのコンテナイメージを作成する開発者向けに、Dockerfile の作成と最適化を案内するリファレンススキルです。命令の使い方、言語別のマルチステージ構成、レイヤーキャッシュ、本番向けの強化を扱い、イメージのビルド実行やオーケストレーションは対象外です。

主な機能

  1. 01一般的な Dockerfile 命令と使い方のリファレンス
  2. 02Go、Java、Node.js、Python 向けのマルチステージ構成
  3. 03レイヤーキャッシュと依存ファイルを先にコピーする指針
  4. 04イメージの縮小、セキュリティ、本番向けの強化
  5. 05よくある Dockerfile の問題への対処

活用シーン

  1. 01アプリケーションの実行環境向け Dockerfile の作成
  2. 02依存レイヤーとビルドキャッシュの最適化
  3. 03Dockerfile のセキュリティと本番利用への適合確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/full-stack-skills/docker-skills --skill docker-dockerfile

インストール後、Claude Code で/docker-dockerfileを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evaluation-report.html
agents/
openai.yaml
examples/
01-multi-stage-go.md
02-multi-stage-java.md
03-spring-boot-layers.md
04-multi-stage-node.md
05-multi-stage-python.md
references/
01-dockerfile-instructions.md
02-layer-caching.md
03-dockerignore.md
04-image-size-optimization.md
05-multi-stage-patterns.md

詳細

Dockerfile — 完全ガイド

本番環境向けの Dockerfile を作成するためのエキスパート向けリファレンスです。すべての命令、パターン、最適化を網羅します。

使用する場面

ユーザーが次の内容に言及した場合は、必ずこのスキルを使用してください。

  • 「Dockerfile」、「Dockerfile の書き方」、「Dockerfile の命令」
  • 「マルチステージビルド」、「multi-stage build」
  • 「Dockerfile のレイヤー最適化」、「layer caching」
  • 「Dockerfile テンプレート」、言語固有のもの:「Go Dockerfile」、「Java Dockerfile」、「Python Dockerfile」
  • Dockerfile の作成または最適化が必要な場合
  • 「Dockerfile のベストプラクティス」

命令リファレンス

FROM — ベースイメージ
FROM <image>[:<tag>] [AS <stage-name>]
FROM alpine:3.20                           # Tag
FROM alpine:3.20@sha256:abc123...def456     # Digest (production!)
FROM golang:1.22-alpine AS builder          # Named stage
FROM scratch                                 # Empty image (for static binaries)
ベストプラクティス理由
本番環境ではダイジェストを固定するタグは変更可能ですが、ダイジェストは不変です
Alpine/slim バリアントを使用する攻撃対象領域とイメージサイズを小さくできます
Go/Rust では FROM scratch を使用する静的バイナリにはほかに何も必要ありません
RUN — コマンドを実行する
# ✅ Chain commands, clean in same layer
RUN apk add --no-cache curl && \
    curl -fsSL https://example.com/script.sh -o /usr/local/bin/script && \
    chmod +x /usr/local/bin/script

# ❌ Each RUN = new layer (bloat)
RUN apk add curl
RUN curl ... -o /usr/local/bin/script
RUN chmod +x /usr/local/bin/script

# Multi-line readability
RUN set -eux; \
    apk add --no-cache \
      curl \
      ca-certificates \
      tzdata; \
    curl -fsSL ... | tar xz -C /usr/local
COPY — ファイルをコピーする
COPY [--chown=<user>:<group>] <src>... <dest>
COPY . /app
COPY --chown=app:app ./binary /usr/local/bin/
COPY --from=builder /app/build /app       # From another stage (multi-stage)
# ✅ Layer-friendly: copy deps first, then source
COPY go.mod go.sum ./
RUN go mod download
COPY . .

# ❌ Source change invalidates dependency cache
COPY . .
RUN go mod download
ADD — コピーと自動展開
# ADD auto-extracts tar archives
ADD archive.tar.gz /app/

# Prefer COPY unless you need tar extraction
COPY archive.tar.gz /app/
RUN tar xzf /app/archive.tar.gz -C /app
WORKDIR — 作業ディレクトリを設定する
WORKDIR /app
# All subsequent RUN/COPY/CMD use /app as base

# Prefer over:
RUN cd /app && npm install   # ❌ cd doesn't persist
ENV と ARG
# ARG: build-time only (not in final image)
ARG VERSION=1.0.0
FROM myapp:${VERSION}

# ENV: runtime (persists in image)
ENV NODE_ENV=production \
    PORT=8080

# Combine: pass ARG to ENV
ARG APP_VERSION
ENV APP_VERSION=${APP_VERSION}
EXPOSE — ポートを記述する
EXPOSE 8080
EXPOSE 8080/tcp     # Protocol-specific
EXPOSE 8080/udp

# Note: EXPOSE does NOT publish ports. Use -p at runtime:
# docker run -p 8080:8080 myapp
CMD と ENTRYPOINT
# CMD: default command (overridable)
CMD ["nginx", "-g", "daemon off;"]
# docker run myimage echo hello → overrides CMD

# ENTRYPOINT: fixed entry (not overridable)
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
# docker run myimage → runs: docker-entrypoint.sh nginx -g 'daemon off;'
# docker run myimage echo hello → runs: docker-entrypoint.sh echo hello

# Common pattern: script + default args
ENTRYPOINT ["/entrypoint.sh"]
CMD ["start"]
USER — root 以外のユーザーに切り替える
# Create user and group
RUN addgroup --system app && adduser --system --ingroup app app
USER app
HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8080/health || exit 1

# Dockerfile without shell (scratch):
HEALTHCHECK --interval=30s CMD /app/healthcheck || exit 1
SHELL — デフォルトのシェルを変更する
SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]
RUN echo "Now using bash with strict mode"

マルチステージビルドのパターン

パターン 1:バイナリをビルドして scratch を使用(Go/Rust)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o server .

FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/server /server
USER 1000:1000
CMD ["/server"]
パターン 2:ビルドして最小限のランタイムを使用(Java)
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
RUN addgroup --system app && adduser -S -G app app
COPY --from=builder /app/target/*.jar /app.jar
USER app
CMD ["java", "-jar", "/app.jar"]
パターン 3:レイヤーを最適化(Spring Boot)
FROM eclipse-temurin:21-jre-alpine AS builder
WORKDIR /app
COPY build/libs/*.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract

FROM eclipse-temurin:21-jre-alpine
RUN addgroup --system app && adduser -S -G app app
# Layers in dependency order (max cache)
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./
USER app
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
パターン 4:ビルドして Alpine を使用(Node.js)
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
RUN addgroup --system app && adduser -S -G app app
COPY --from=builder /app/dist /app
COPY --from=builder /app/node_modules /app/node_modules
USER app
CMD ["node", "/app/index.js"]
パターン 5:Python の依存関係と slim ランタイム
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

FROM python:3.12-slim
RUN groupadd --system app && useradd --system -g app app
COPY --from=builder /root/.local /home/app/.local
COPY . /app
ENV PATH=/home/app/.local/bin:$PATH
USER app
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]

レイヤーキャッシュ戦略

Docker builds layers from top to bottom.
A changed layer invalidates ALL layers below it.

✅ CORRECT order:
  FROM base                  ← rarely changes
  RUN install-system-deps    ← changes with system updates
  COPY go.mod go.sum ./      ← changes with dependency changes
  RUN go mod download        ← changes with dependency changes
  COPY . .                   ← changes every commit ← MUST BE LAST

❌ WRONG order (slow builds):
  COPY . .                   ← changes every commit
  RUN go mod download        ← reruns every time!

.dockerignore

# .dockerignore
.git
.gitignore
*.md
.env
.env.*
Dockerfile
docker-compose*.yml
node_modules
__pycache__
*.pyc
.git
.idea
.vscode
*.log
tmp/

ワークフロー — 推奨される作成手順

Step 1:言語とランタイムを決める:Go/Java/Node.js/Python → ベースイメージを選択 Step 2:ビルド方式を選ぶ:単一ステージ/マルチステージ/Spring Boot のレイヤー化 → templates からテンプレートを選択 Step 3:Dockerfile を作成する:まず依存関係を COPY → RUN install → ソースコードを COPY → CMD Step 4:検証する:docker build -t app . + docker run + dive でイメージサイズを分析 Step 5:本番向けに強化する:root 以外の USER、HEALTHCHECK、ダイジェストの固定、セキュリティチェック

注意点 — よくある落とし穴

  • RUN install より前に COPY . . を実行する:コードを変更するたびに依存関係のレイヤーが無効になり、最初から再ビルドされます。→ 対処方法:依存関係を先にコピーします:COPY package.json . → RUN install → COPY src/ .。
  • デフォルトで root ユーザーを使用する:Dockerfile の最後には必ず USER <non-root> を指定してください。root としてコンテナから脱出されると、ホストでも root 権限を得られます。→ 対処方法:RUN addgroup -S app && adduser -S app -G app と USER app を追加し、docker exec myapp whoami で確認します。
  • Dockerfile に ENV SECRET=value を記述する:値はイメージのレイヤーに永久に含まれます。→ 対処方法:BuildKit の --mount=type=secret または実行時の環境変数注入 docker run -e SECRET=$VAL を使用します。
  • .dockerignore がない:プロジェクト全体がビルドコンテキストに送られ、処理が遅くなり、機密ファイルが漏えいするおそれがあります。→ 対処方法:最低限 .git node_modules .env を含む .dockerignore を作成し、docker build --no-cache . 2>&1 | head -1 で確認します。
  • クリーンアップせずに RUN apt update && apt install を実行する:パッケージリストがレイヤーに残ります。→ 対処方法:&& rm -rf /var/lib/apt/lists/* を連結します。apk の場合は --no-cache フラグを使用します。
  • サイズの大きいベースイメージを使う:ubuntu:22.04(77 MB)に対し、alpine:3.20 は 7 MB です。→ 対処方法:Alpine を優先します。glibc が必要な場合は debian:bookworm-slim を使用し、docker images でサイズを確認します。

対応範囲 — 対応可能なこと/できないこと

分類場面説明
✅ 対応可能本番環境向け Dockerfile の作成14 個の命令を網羅したリファレンスとベストプラクティス
✅ 対応可能マルチステージビルド(Go/Java/Node/Python)言語ごとのテンプレートを 5 種類用意
✅ 対応可能レイヤーキャッシュの最適化依存関係を先に COPY → RUN をまとめる → BuildKit の cache mount
✅ 対応可能イメージのスリム化5 ステップの手順:マルチステージ→Alpine→distroless→クリーンアップ→dive
⚠️ 条件付きプライベート依存関係のインストールBuildKit の --secret または SSH forwarding が必要
⚠️ 条件付きCMD と ENTRYPOINT の選択命令リファレンスの判断ツリーを参照してください(ツールには ENTRYPOINT、サービスには CMD)
❌ 対象外docker build コマンドの実行docker-build を使用
❌ 対象外マルチプラットフォームビルド(arm64/amd64)docker-buildx を使用
❌ 対象外コンテナオーケストレーション(複数コンテナ)docker-compose を使用

このスキルを使用しない場合

❌ 使用しない✅ 代わりに使用
イメージのビルド(docker build ...)docker-build
マルチプラットフォームビルドdocker-buildx
Compose ファイルの作成docker-compose
Docker の基礎docker-basics
コンテナの実行docker-run

セキュリティと安定性

  • Dockerfile のテンプレートはすべて学習用です。本番環境で使用する前に確認し、セキュリティを強化してください。
  • Dockerfile にシークレットを埋め込まないでください。BuildKit の --mount=type=secret または実行時の注入を使用してください。
  • 本番環境では必ず USER <non-root> を使用してください。そのユーザー用のファイルをコピーするときは、COPY --chown を使用してください。
  • 本番環境で再現性を確保するため、ベースイメージのダイジェストを固定してください。

📚 公式ドキュメントの参考情報

ドキュメントURL
Dockerfile リファレンスhttps://docs.docker.com/reference/dockerfile/
Docker Build の概要https://docs.docker.com/build/
ビルドのベストプラクティスhttps://docs.docker.com/build/building/best-practices/
マルチステージビルドhttps://docs.docker.com/build/building/multi-stage/
.dockerignorehttps://docs.docker.com/build/building/context/#dockerignore-files
イメージレイヤーとキャッシュhttps://docs.docker.com/build/cache/

🧭 Docker スキルの進め方

📍 現在の位置:docker-dockerfile — Dockerfile の作成

basics → dockerfile → build → buildx → run → compose → ...

→ 次へ:docker-build — docker build でイメージをビルド

コメント