Dockerイメージを自分でカスタマイズするにはDockerfileを書く必要があります。この記事ではDockerfileの書き方・命令の意味・ベストプラクティスまで実践的に解説します。
Dockerfileとは?
DockerfileはDockerイメージを作成するための手順書テキストファイルです。「どのOSをベースにするか」「どのパッケージをインストールするか」「どのコマンドを実行するか」をステップごとに記述します。docker buildコマンドを実行するとDockerfileを読んで自動的にイメージが作成されます。
Dockerfile命令一覧
| 命令 | 説明 | 例 |
|---|---|---|
FROM | ベースイメージを指定(必須・最初に書く) | FROM ubuntu:22.04 |
RUN | ビルド時にコマンドを実行 | RUN apt-get install -y nginx |
COPY | ホストからファイルをコピー | COPY app.py /app/ |
ADD | COPYの拡張版(URL・tar展開も可) | ADD archive.tar.gz /app/ |
CMD | コンテナ起動時のデフォルトコマンド | CMD ["python3", "app.py"] |
ENTRYPOINT | コンテナのメインコマンド(上書き不可) | ENTRYPOINT ["nginx"] |
ENV | 環境変数を設定 | ENV PORT=8080 |
ARG | ビルド時の変数(実行時には使えない) | ARG VERSION=1.0 |
WORKDIR | 作業ディレクトリを設定 | WORKDIR /app |
EXPOSE | コンテナが使用するポートを明示 | EXPOSE 80 |
USER | 実行ユーザーを変更 | USER appuser |
VOLUME | マウントポイントを定義 | VOLUME ["/data"] |
LABEL | メタデータを付与 | LABEL version="1.0" |
HEALTHCHECK | ヘルスチェックコマンドを設定 | HEALTHCHECK CMD curl -f http://localhost/ |
基本的なDockerfileの例
Python Flaskアプリ
# ベースイメージを指定
FROM python:3.11-slim
# 作業ディレクトリを設定
WORKDIR /app
# 依存関係ファイルをコピーしてインストール
# (requirements.txtを先にコピーするとキャッシュが効く)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# アプリのソースコードをコピー
COPY . .
# 非rootユーザーで実行(セキュリティ)
RUN useradd -r appuser
USER appuser
# ポートを明示
EXPOSE 5000
# 起動コマンド
CMD ["python3", "app.py"]
Nginxカスタム設定
FROM nginx:1.25-alpine
# デフォルト設定を削除してカスタム設定をコピー
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/
# 静的ファイルをコピー
COPY html/ /usr/share/nginx/html/
# ヘルスチェック設定
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
マルチステージビルド
マルチステージビルドを使うと、ビルドツールを最終イメージに含めず、軽量なイメージを作れます。
# ステージ1:ビルド環境(Goの例)
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .
# ステージ2:実行環境(最小限)
FROM alpine:3.19
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# builderステージからバイナリだけコピー
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]
ビルドツール(Go SDK)は最終イメージに含まれず、実行バイナリだけが入った数十MBの軽量イメージが完成します。
Dockerfileのベストプラクティス
① レイヤーキャッシュを活用する
Dockerfileの各命令はレイヤーを作成します。変更が少ない命令(パッケージインストールなど)を先に書き、変更が多い命令(COPYなど)を後に書くとビルドキャッシュが効いて高速になります。
# 良い例:依存関係を先にインストール(キャッシュが効く)
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . . # ソースコードの変更でもpip installはキャッシュ利用
# 悪い例:全ファイルを先にコピー(毎回pip installが走る)
COPY . .
RUN pip install -r requirements.txt
② RUN命令をまとめる
# 悪い例:RUN命令が多くレイヤーが増える
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y wget
RUN rm -rf /var/lib/apt/lists/*
# 良い例:&&でまとめてレイヤーを削減
RUN apt-get update \
&& apt-get install -y curl wget \
&& rm -rf /var/lib/apt/lists/*
③ .dockerignoreを使う
.dockerignoreファイルでビルドコンテキストから除外するファイルを指定できます。不要なファイルをイメージに含めないようにします。
# .dockerignoreの例
.git
.gitignore
*.md
node_modules
__pycache__
.env
*.log
tests/
イメージのビルドと確認
# イメージをビルド
docker build -t myapp:1.0 .
# タグを複数付けてビルド
docker build -t myapp:1.0 -t myapp:latest .
# ビルドARGを渡す
docker build --build-arg VERSION=2.0 -t myapp:2.0 .
# ビルドの詳細を表示
docker build --progress=plain -t myapp:1.0 .
# イメージのレイヤー構造を確認
docker history myapp:1.0
# イメージの詳細情報
docker inspect myapp:1.0
まとめ
- DockerfileはDockerイメージを作成するためのテキスト形式の手順書
- FROM・RUN・COPY・CMD・WORKDIRが最もよく使う命令
- マルチステージビルドでビルドツールを含まない軽量イメージを作れる
- 変更が少ない命令を先に書くとレイヤーキャッシュが効いてビルドが速くなる
.dockerignoreで不要なファイルをビルドコンテキストから除外しよう



コメント