Dockerは 現代のソフトウェア開発に欠かせないツールとなり、チームはこれまでにない一貫性と容易さでアプリケーションを構築、リリース、実行できるようになりました。このコンテナ化の魔法の中核を成すのが、Dockerイメージ作成の青写真として機能する、シンプルでありながら強力なスクリプトであるDockerfileです。
効果的なDockerfileビルドプロセスを構築することは、単なる技術的な演習ではありません。開発サイクルの高速化、アプリケーションのフットプリントの小型化とセキュリティ強化、そしてデプロイメントの信頼性向上への道筋となるのです。Dockerを初めて使う方にも、スキルアップを目指す方にも、このガイドは実用的で効率的かつ安全なDockerfileを作成するための基本を解説します。.
Dockerエコシステムを理解する:簡単な復習

Dockerfiles の詳細に入る前に、主要な Docker の概念について簡単に触れておきましょう。
- イメージ: イメージは、コード、ランタイム、ライブラリ、環境変数、設定ファイルなど、ソフトウェアの実行に必要なすべてのものを含む、軽量でスタンドアロンの実行可能パッケージです。 イメージ は不変のテンプレートです。
- コンテナ: コンテナは、イメージの実行可能なインスタンスです。コンテナは作成、起動、停止、移動、削除することができ、アプリケーションに隔離された環境を提供します。
- Dockerfile: これが今回の焦点です。Dockerfileは、Dockerがイメージを自動的に組み立てるために使用する一連のコマンドを記述したテキストドキュメントです。
- Docker Hub/レジストリ: これらは、コード用の GitHub に似た、Docker イメージを保存および共有するためのリポジトリです。
適切に作成された Dockerfile は、 イメージを作成する 可能な限り軽量で、構築が速く、安全な
Dockerビルドフラグの説明
- -t myapp:1.0: このフラグは、イメージに名前 (myapp) とバージョン (1.0) をタグ付けします。タグ付けはバージョン管理に役立ち、特にデプロイやレジストリへのプッシュ時に、後で特定のイメージビルドを参照しやすくなります。
- . (ドット): これはビルドコンテキスト、つまりDockerがDockerfileやビルド中に必要なその他のファイル(イメージにコピーするファイルなど)を探すディレクトリを指します。Docker
はこのディレクトリの内容を圧縮してDockerデーモンに送信します。ビルドプロセス中は、ビルドコンテキスト内のファイルのみにアクセスできることに注意してください。
基本的なDockerfileの指示:構成要素

最も一般的な指示と、それらを効果的に使用する方法を見てみましょう。.
- から: すべてのDockerfileはFROM命令で始まる必要があります。これは、イメージを構築するベースイメージを指定します。.
- 目的: 開始点を選択します。通常は、オペレーティング システム (Ubuntu:22.04 など) または事前構成されたアプリケーション ランタイム (node:18-alpine など) です。.
- 例: FROM python:3.9-slim
- ベストプラクティス: アプリケーションのニーズを満たす最小限のベースイメージを選択してください。Alpine バージョンはサイズが非常に小さいですが、musl libc を使用しているため、一部の C 言語依存パッケージとの互換性に問題が生じる可能性があります。Slim バージョンは、glibc を搭載した標準ディストリビューション (Debian など) の軽量版を提供するため、良い妥協案となります。
- WORKDIR: この設定はwを設定します後続の RUN、CMD、ENTRYPOINT、COPY、および ADD 命令のワーキング ディレクトリ。.
- 目的: 後続のファイル操作およびコマンド実行のために、イメージ内の現在のディレクトリコンテキストを定義します。ディレクトリが存在しない場合は、Dockerが作成します。
- 例: WORKDIR /usr/src/app
- ベストプラクティス: WORKDIR には絶対パスを使用してください。WORKDIR を使用してディレクトリを複数回変更する方が、RUN 命令内で cd コマンドを連鎖させるよりも一般的に簡潔です。
- コピー: ビルド コンテキストからイメージのファイル システムにファイルまたはディレクトリをコピーします。.
- 目的: アプリケーション コード、構成ファイル、その他の必要なアセットをイメージに追加します。
- 例:
Dockerfile
WORKDIR /usr/src/app
COPY package.json ./
COPY src/ ./src/
- ベストプラクティス: 単純なファイルコピーには、ADDよりもCOPYを使用することをお勧めします。COPYの方が分かりやすいためです。ADDにはURLのダウンロードやtarファイルの解凍といった追加機能がありますが、動作が予測しにくい場合があります。ダウンロードや解凍が必要な場合は、明確さとセキュリティの観点から、curl、wget、tarなどのツールをRUNコマンドで使用することをお勧めします。
- 走る: 現在のイメージの上に新しいレイヤーを作成し、コマンドを実行し、結果をコミットします。ソフトウェアのインストール、ディレクトリの作成、コードのコンパイルなどに使用されます。.
- 目的: パッケージのインストール、ビルドスクリプトの実行、または設定の変更によって、イメージのファイルシステムを変更すること。
- 例:
Dockerfile
RUN apt-get update && apt-get install -y –no-install-recommends \
nginx \
curl \
&& rm -rf /var/lib/apt/lists/*
- ベストプラクティス: && を使用して関連コマンドを連結し、一時ファイルやパッケージマネージャのキャッシュ(Debian/Ubuntu の場合は rm -rf /var/lib/apt/lists/*、CentOS/RHEL の場合は yum clean all など)を同じ RUN 命令内でクリーンアップします。各 RUN 命令が新しいレイヤーを作成するため、この方法でレイヤーの数を最小限に抑え、イメージサイズを削減できます。
- 環境: ビルド プロセス中 (定義された後) およびイメージからコンテナーを実行するときに使用できる環境変数を設定します。.
- 目的: アプリケーションまたはビルド スクリプトに必要な構成値、パス、または設定を提供します。
- 例:
Dockerファイル
ENV NODE_ENV=production
ENV APP_PORT=3000
- ベストプラクティス: 機密性が低い設定データには ENV を使用してください。機密情報には ENV を使用してイメージに焼き込むのではなく、ランタイムインジェクションメソッドを使用してください。
- 議論: Docker ビルド中にユーザーが --build-arg フラグを使用して渡すことができるビルド時変数を定義します。.
- 目的: Dockerfile を変更せずにビルド プロセスのパラメーター化を可能にします。
- 例: Dockerfile
Dockerfile
ARG APP_VERSION=1.0.0
ENV APP_VERSION_ENV=${APP_VERSION}
RUN echo “バージョン ${APP_VERSION_ENV} をビルドしています”
- ビルドに使うもの: バッシュ docker ビルド – ビルド引数 APP_VERSION=1.2.3 -t myapp.
- 注意: 上記のように、明示的に ENV 変数として設定されない限り、ARG 変数は実行中のコンテナーでは使用できません。
- さらす: 実行時にコンテナが指定されたネットワーク ポートをリッスンすることを Docker に通知します。.
- 目的: このドキュメントは主にイメージ作成者とユーザー向けのドキュメントとして機能します。ポートを公開するものではありません。
例:
Dockerfile
EXPOSE 8080
- 注: ホストからポートにアクセスできるようにするには、docker run で -p または -P フラグを使用します (例: docker run -p 8080:8080 myimage)。.
- 司令官 そして エントリーポイント: コンテナの起動時に実行されるコマンドを定義します。.
- CMD [“executable”, “param1”, “param2”]: 実行中のコンテナのデフォルト設定を指定します。これらのデフォルト設定は、docker run にコマンドを追加することで簡単に上書きできます。複数の CMD を指定した場合、最後に指定した CMD のみが有効になります。
- ENTRYPOINT [“executable”, “param1”, “param2”]: コンテナを実行可能ファイルとして実行するように設定します。docker run に渡された引数は、ENTRYPOINT コマンドに追加されます。
- 例(典型的なパターン):
Dockerfile
ENTRYPOINT [“python”, “app.py”] # メインコマンド
CMD [“–help”] # docker run で引数が指定されていない場合のデフォルト引数
- ベストプラクティス: 簡単に上書き可能なデフォルトコマンドが必要な場合は、CMD を使用してください。ENTRYPOINT を使用すると、特定の実行可能ファイルのように動作するイメージを作成できます。多くの場合、CMD を使用してデフォルト引数を指定します。Web アプリケーションの場合、CMD [“npm”, “start”] または CMD [“python”, “manage.py”, “runserver”] が標準です。
最適化された Dockerfile の主なベストプラクティス

機能的なDockerfileを書くことはほんの始まりに過ぎません。最適化することで大きなメリットがもたらされます。.
- ビルド キャッシュを効果的に活用する: Dockerはイメージをレイヤーごとにビルドし、可能であれば以前のビルドのレイヤーを再利用しようとします(キャッシュ)。キャッシュヒットを最大化するには、以下の手順を実行します。
- 変更頻度の低い命令から高い命令へと順序付けます。例えば、頻繁に変更される 前に アプリケーションのソースコードをコピーする
Dockerfile
# Node.jsアプリの優れたキャッシュ例
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./ # 依存関係は変更頻度が低い
RUN npm ci –omit=dev # パッケージファイルが変更されない場合、このレイヤーはキャッシュされます
COPY . . # ソースコードは頻繁に変更されるため、最後に配置
CMD [“node”, “server.js”]
- 画像を小さく保つ: イメージが小さいほど、プル、プッシュ、デプロイが高速になり、攻撃対象領域が縮小されます。.
- 最小限のベースイメージを使用する: Alpine、slim、または distroless バリアントは、完全な OS イメージよりも大幅に小さくなります。
- 同じ RUN レイヤーでクリーンアップ: パッケージをインストールした後、同じRUN命令を使って不要なキャッシュや一時ファイルを削除します。例:
- Debian/Ubuntu: apt-get clean && rm -rf /var/lib/apt/lists/*
- CentOS/RHEL: yum clean all または dnf clean all
- アルパイン: rm -rf /var/cache/apk/*
- マルチステージビルドを採用する: これは、特にコンパイルされた言語やビルド ステップのあるアプリケーション (JavaScript フロントエンドなど) の場合に、イメージ サイズを縮小する最も効果的な方法の 1 つです。.
- コンセプト: すべてのビルドツールと開発依存関係を含む1つのステージ(FROMブロック)を使用してアプリケーションをコンパイル/ビルドします。次に、 新しい ステージを開始し、COPY-from=を使用します。 のみが含まれる この最終的なクリーンな段階には、必要なコンパイル済み成果物
- 例(簡略化されたGoアプリケーション):Dockerfile
Dockerfile
# ステージ 1: ビルド
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# ステージ 2: ランタイム
FROM debian:bullseye-slim
WORKDIR /app
COPY –from=builder /app/myapp .
CMD [“./myapp”]
- ビルダー ステージには Go SDK がありますが、最終イメージにはコンパイルされたバイナリと最小限の Alpine OS のみが含まれています。.
- セキュリティを優先する:
- 非ルートユーザーとして実行: デフォルトでは、コンテナはルートユーザーとして実行されます。これはセキュリティリスクです。Dockerfileに専用の非特権ユーザーとグループを作成し、USER命令を使用して切り替えてください。Dockerfile
Dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# … ファイルをコピーして、所有者を appuser:appgroup に変更します …
USER appuser
- 必要なパッケージのみをインストールする: すべてのパッケージは潜在的な脆弱性を秘めています。本番環境イメージにデバッグツールや開発ユーティリティをインストールすることは避けてください(マルチステージビルドを使用してください)。
- 機密情報をハードコーディングしないでください。 パスワード、APIキー、その他の機密情報をDockerfile(環境変数など)に記述することは避けてください。Dockerシークレット、Kubernetesシークレット、または実行時に安全に提供される環境変数など、実行時注入方式を使用してください。
- .dockerignore を効果的に使用するには、 ビルドコンテキストのルート(Dockerfile と同じ階層)に .dockerignore ファイルを作成します。Docker デーモンに送信しないファイルとディレクトリをリストします(例:.git、イメージにインストールされている場合は node_modules、ローカル IDE 設定、*.log)。
- Dockerのビルドプロセスを高速化します ビルドコンテキストのサイズを縮小し、機密ファイルや不要なファイルがイメージに含まれるのを防ぐことで、
基本を超えて:さらなる強化

上記に慣れたら、さらに優れた Dockerfile を作成するために以下を検討してください。
- BuildKit: Dockerの新しいビルドエンジンで、多くの場合デフォルトで有効になっています。パフォーマンスの向上(並列ビルド)、キャッシュ機能の改善、パッケージマネージャー向けのビルドシークレット(RUN– mount=type=secret,…)やキャッシュマウント(RUN– mount=type=cache,…)などの高度な機能を提供します。有効になっていることを確認するか、DOCKER_BUILDKIT=1で有効にしてください。
- Dockerfile の Lint 処理: Hadolint (hadolint Dockerfile) などのツールを使用して、ビルド前に Dockerfile のエラー、スタイル違反、ベスト プラクティスへの準拠を静的に分析します。
よくあるトラブルシューティングのクイックヒント
- 中に「ファイルが見つかりません」というエラーが発生した場合 COPY または ADD 実行: ソースパス(ビルドコンテキストのルートからの相対パス)を再確認し、ファイルが .dockerignore によって除外されていないことを確認してください。
- ビルドが遅い場合: キャッシュを最適化するために命令の順序を確認してください。可能な場合はRUNコマンドを組み合わせます。.dockerignoreが包括的であることを確認してください。
- 大きなイメージ: マルチステージビルドを使いましょう!RUNレイヤーでクリーンアップを行いましょう。ベースイメージは最小限に抑えましょう。
DevOps ワークフローにおける Dockerfiles
Dockerfile は、「Infrastructure as Code」の重要な要素です。
- バージョン管理: Dockerfile を常にアプリケーション コードと一緒に Git リポジトリにコミットします。
- CI/CD統合: 継続的インテグレーション/継続的デリバリーパイプライン(GitHub Actions、Jenkins、GitLab CIなど)内で、Dockerビルドとイメージプッシュプロセスを自動化します。これにより、一貫性と繰り返し性を確保したビルドとデプロイメントが可能になります。
結論:成功の基盤を築く
効果的なDockerfileを作成することは、開発スピード、運用の信頼性、そしてアプリケーションのセキュリティにおいて大きなメリットをもたらす投資です。基本的な手順を習得し、マルチステージビルドやイメージレイヤーの慎重な管理といったベストプラクティスを実践し、セキュリティを最優先することで、無駄がなく、効率的で、堅牢なDockerイメージを作成できます。.
このガイドはしっかりとした基礎を提供します。Dockerを使い続ける中で、Dockerfileの探求、実験、改良を続けてください。.
Docker と DevOps の実践を向上させる準備はできていますか?
は Seahawk Media、コンテナ化、クラウドテクノロジー、そして合理化されたCI/CDパイプラインの可能性を最大限に活用できるよう、企業を支援することに特化しています。アプリケーションのデプロイメントの最適化、セキュリティの強化、開発ライフサイクルの加速など、お客様のご要望に専門チームがお応えします。