Dock Stay
イメージをビルドする - docker build の使い方・オプション・サンプル

イメージをビルドする - docker build

Dockerfile からイメージをビルドするコマンド。ビルドコンテキスト、`-f` の Dockerfile 指定、`-t` のタグ付け、BuildKit のキャッシュ最適化、`--target` によるマルチステージ制御を押さえる。

概念図

docker build diagram

構文

bash
docker build [OPTIONS] PATH | URL | -

実例

カレントディレクトリをコンテキストにビルドしタグ付け

bash
docker build -t myapp:latest .

別パスの Dockerfile とセマンティックバージョンタグを指定

bash
docker build -f docker/Dockerfile.prod -t myapp:1.2.3 .

BuildKit 有効化でマルチステージの特定ステージまでビルド

bash
DOCKER_BUILDKIT=1 docker build --target builder -t myapp:build .

ビルドの流れ

docker build . のドット部分がビルドコンテキスト。

Docker CLI はこのディレクトリ配下を tar でまとめてデーモンに送り、Dockerfile の各命令を順に実行する。

このため巨大な node_modules/.git/ が含まれているとコンテキスト送信だけで数十秒かかる。

.dockerignore に除外パターンを書いて送る量を減らすこと。

ビルドの中間レイヤーはキャッシュされる。

Dockerfile の上から順に、ファイルや命令に変化がない行はキャッシュが再利用される。

逆に言えば、頻繁に変わる COPY . . を上に置くとその後の RUN npm ci もキャッシュされない。

依存ファイル(package.json)を先にコピーして npm ci し、最後にソースをコピーするのが定石。

bash
# .dockerignore
node_modules
.git
*.log
dist

タグ付けと命名規則

タグは REGISTRY/NAMESPACE/REPO:TAG の形式。

docker build -t myapp:latest . は暗黙に docker.io/library/myapp:latest を意味する。

GHCR なら ghcr.io/owner/myapp:1.2.3、ECR なら 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:1.2.3 のようにレジストリ URL ごと含める。

:latest タグはデプロイ時に事故を招きやすい。

ロールバックができない、どの時点のイメージか特定できない、Kubernetes が常に pull しようとするなどの問題がある。

CI ではコミット SHA(myapp:git-abc1234)やセマンティックバージョン(myapp:1.2.3)で固定し、:latest は開発用途に限定するのが安全。

bash
docker build -t ghcr.io/acme/myapp:1.2.3 -t ghcr.io/acme/myapp:latest .
docker push ghcr.io/acme/myapp:1.2.3

BuildKit を有効にする

BuildKit は Docker 23 以降のデフォルトビルダーで、並列ビルド、キャッシュマウント、シークレットマウント、マルチプラットフォームビルド(--platform=linux/amd64,linux/arm64)をサポートする。

古い Docker では DOCKER_BUILDKIT=1 を環境変数で指定するか、/etc/docker/daemon.json"features": { "buildkit": true } を書く。

キャッシュマウントは RUN --mount=type=cache,target=/root/.npm npm ci のように書くと、npm のダウンロード済みパッケージをビルド間で保持できる。

CI で毎回クリーンビルドする環境ではこのキャッシュが大きな高速化になる。

--target builder でマルチステージの途中ステージだけをビルドすれば、テスト用の軽量イメージを作るのも容易になる。

bash
# syntax=docker/dockerfile:1.7
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

関連トピック