Dockerfile構文と実践的なビルド戦略

Dockerfileは、Dockerイメージを自動化・再現可能に構築するための宣言的スクリプトであり、一連のレイヤー化された命令によって、ベースイメージから最終的な実行環境を段階的に構成します。このプロセスは単なるファイルコピーではなく、コンテナライフサイクル全体を設計するための基盤技術です。

基本原則と実行モデル

  • すべての命令(FROM, RUN, COPYなど)は大文字で記述し、1行につき1命令が推奨されます。
  • 命令は上から順に逐次実行され、各命令ごとに新しいファイルシステムレイヤーが作成・コミットされます。
  • #で始まる行はコメントとして無視されます。
  • ビルド中、Dockerエンジンは「仮想コンテナ」を起動し、命令を適用 → コミット → 次のレイヤーへ移行する反復処理を実行します。

主要命令の役割とベストプラクティス

FROM:信頼できるベースの選択

イメージ構築の起点を指定します。タグやSHA-256ダイジェストによる明示的なバージョン指定がセキュリティと再現性を担保します。

FROM python:3.11-slim@sha256:9a7c0e8f4b1d...  # ダイジェスト指定(推奨)
FROM nginx:1.25-alpine                         # 明確なタグ指定

RUN:レイヤー効率を意識したパッケージ管理

インストールや設定などの変更を含む命令は、複数のRUNを1つにまとめてレイヤー数を削減すべきです。

# 非推奨:不要なレイヤーが増加
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# 推奨:1つのRUNで完結
RUN apt-get update && \
    apt-get install -y curl jq && \
    rm -rf /var/lib/apt/lists/*

COPY vs ADD:意図を明確に分ける

  • COPY:ローカルファイル/ディレクトリの単純な転送(権限・タイムスタンプを保持)。
  • ADD:URL取得やtar自動展開など高度な機能を持つが、過剰な機能は可読性と予測可能性を損なうため、COPYを優先します。

WORKDIR:パス解決の明確化

絶対パスを指定し、相対パス依存を排除することで、COPY/RUN命令の動作を安定させます。

WORKDIR /app  # 必ず絶対パス
COPY . .
RUN pip install -r requirements.txt

ENVARG:構築時と実行時の分離

  • ARG:ビルド時にのみ有効なパラメータ(例:--build-arg BUILD_VERSION=1.2.0)。
  • ENV:コンテナ実行時にも継承される環境変数。ただし、機密情報はマウントや外部シークレットで扱うべきです。

ENTRYPOINTCMD:起動ロジックの責務分離

ENTRYPOINTはアプリケーションの実行エントリポイント(不変部分)、CMDはそのデフォルト引数(可変部分)として設計します。

FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt

# ENTRYPOINT:固定コマンド(uvicornサーバー)
ENTRYPOINT ["uvicorn"]
# CMD:デフォルト引数(アプリモジュールとオプション)
CMD ["main:app", "--host", "0.0.0.0:8000", "--reload"]

この設計により、docker run myapi --host 0.0.0.0:9000のように引数を上書き可能になります。

実用例:FastAPIサービスの最適化Dockerfile

以下は、マルチステージビルドと最小限のランタイムイメージを活用した実装例です。

# ビルドステージ
FROM python:3.11-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /build/wheels -r requirements.txt

# 実行ステージ
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /build/wheels /wheels
COPY --from=builder /usr/local/bin/pip /usr/local/bin/pip
RUN pip install --no-cache /wheels/*.whl && \
    rm -rf /wheels
COPY . .
EXPOSE 8000
USER 1001:1001
ENTRYPOINT ["uvicorn"]
CMD ["main:app", "--host", "0.0.0.0:8000", "--workers", "4"]
  • マルチステージにより、ビルド依存(gccなど)を実行イメージから完全に除外。
  • USER指定でroot権限を回避し、セキュリティを強化。
  • pip wheelによる事前ビルドで、実行環境のサイズと起動時間を削減。

補助機能

.dockerignore:不要なファイルの除外

ビルドコンテキストに含めないファイルを定義し、伝送時間とキャッシュ無効化を防止します。

__pycache__/
.git
*.pyc
*.log
.env

ダングリングイメージの管理

失敗したビルドや不要な中間レイヤーは、docker image prune -fで定期的にクリーンアップします。

タグ: Dockerfile Docker multistage-build fastapi container-security

9月2日 17:06 投稿