Dockerイメージ
イメージ構造、レイヤー、Dockerfile、マルチステージビルド
イメージとは
Dockerイメージはコンテナの設計図です。OS、ランタイム、ライブラリ、 アプリケーションコード、環境変数などすべてを含む読み取り専用のテンプレート。 レイヤー構造で効率的に管理されます。
イメージの構造
イメージレイヤー(積み重ね構造)
レイヤー構造
- • 各命令(RUN, COPY等)が新レイヤーを作成
- • レイヤーは読み取り専用
- • 共通レイヤーはイメージ間で共有
- • Union File Systemで統合して見える
効率性
- • 同じベースイメージは1回だけ保存
- • 変更があったレイヤーのみ再ビルド
- • pull時も差分のみダウンロード
ベースイメージとOS
DockerイメージはOSのユーザースペースを含みます。 カーネルはホストと共有しますが、ライブラリ、シェル、パッケージマネージャ等はイメージ内のものを使用。
alpine約5MB軽量Linux。musl libc + busybox。本番向け。apkパッケージマネージャ。
debian / ubuntu約70-120MBフル機能のLinux。glibc。互換性が高い。apt パッケージマネージャ。
distroless約2-20MBGoogle製。シェル・パッケージマネージャなし。アプリとランタイムのみ。最もセキュア。
scratch0MB空のイメージ。Go等の静的バイナリ向け。OSなし。
ホストOSとの関係
※ コンテナ内のOSはユーザースペースのみ。カーネルはホストのものを使用。
Dockerfile基本
1 # ベースイメージ 2 FROM node:20-alpine 3 4 # メタデータ 5 LABEL maintainer="dev@example.com" 6 7 # 環境変数 8 ENV NODE_ENV=production 9 10 # 作業ディレクトリ 11 WORKDIR /app 12 13 # ファイルコピー 14 COPY package*.json ./ 15 16 # コマンド実行 17 RUN npm ci --only=production 18 19 # アプリケーションコピー 20 COPY . . 21 22 # ポート公開(ドキュメント目的) 23 EXPOSE 3000 24 25 # 実行ユーザー 26 USER node 27 28 # 起動コマンド 29 CMD ["node", "server.js"]
主要な命令
FROMベースイメージを指定。すべてのDockerfileはFROMで始まる
RUNビルド時にコマンド実行。新しいレイヤーを作成
COPY / ADDファイルをイメージにコピー。ADDは展開機能あり
WORKDIR作業ディレクトリを設定
CMD / ENTRYPOINTコンテナ起動時のコマンド。CMDは上書き可、ENTRYPOINTは固定
ENV / ARGENV: 環境変数(実行時も有効)、ARG: ビルド引数(ビルド時のみ)
マルチステージビルド
複数のFROMを使用し、ビルド環境と実行環境を分離。最終イメージサイズを大幅に削減できます。
1 # ビルドステージ 2 FROM node:20 AS builder 3 WORKDIR /app 4 COPY package*.json ./ 5 RUN npm ci 6 COPY . . 7 RUN npm run build 8 9 # 実行ステージ 10 FROM node:20-alpine AS runner 11 WORKDIR /app 12 13 # ビルド成果物のみコピー 14 COPY --from=builder /app/dist ./dist 15 COPY --from=builder /app/node_modules ./node_modules 16 17 USER node 18 CMD ["node", "dist/main.js"]
効果: ビルドツール(npm, tsc等)を含まない軽量イメージが作成される
ベストプラクティス
レイヤーキャッシュを活用
変更頻度の低いものを先にCOPY。package.jsonを先にコピーしてnpm installすると、 コード変更時にnpm installが再実行されない。
軽量ベースイメージを使用
alpine、slim、distroless を検討。alpine は約5MB、通常のubuntuは約70MB。
非rootユーザーで実行
USER命令でroot以外のユーザーを指定。セキュリティ向上。
.dockerignoreを使用
node_modules、.git、ログファイルなど不要なファイルを除外。ビルド高速化。
イメージ操作コマンド
1 # ビルド 2 docker build -t myapp:v1 . 3 docker build -t myapp:v1 -f Dockerfile.prod . 4 5 # タグ付け 6 docker tag myapp:v1 registry.example.com/myapp:v1 7 8 # プッシュ 9 docker push registry.example.com/myapp:v1 10 11 # プル 12 docker pull nginx:latest 13 14 # イメージ一覧 15 docker images 16 17 # イメージ詳細 18 docker inspect myapp:v1 19 docker history myapp:v1 20 21 # 削除 22 docker rmi myapp:v1 23 docker image prune -a # 未使用イメージ削除 24 25 # イメージサイズ確認 26 docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
SRE/インフラ観点
イメージスキャン
- •
docker scout、Trivy、Snyk で脆弱性スキャン - • CI/CDパイプラインに組み込み
- • ベースイメージの定期更新
タグ戦略
- •
latestは本番で使わない - • セマンティックバージョニング: v1.2.3
- • Git SHA: abc123
- • イミュータブルなタグを使用