公開日 2026-06-01

Docker初心者向け: Dockerfile の中身を上から読む――FROM / WORKDIR / COPY / RUN / CMD

Dockerfile の FROM / WORKDIR / COPY / RUN / CMD を最小 PHP サンプルで読み解き、既存 Dockerfile の確認順と修正判断を安定させる。

目次

  1. 1. 記事のゴール
  2. 2. Dockerfile は何をするファイルか
  3. 3. 最小の Dockerfile を見る
  4. 3-1. Dockerfile を作成する
  5. 3-2. app/index.php を作成する
  6. 4. FROM の意味
  7. 5. WORKDIR の意味
  8. 6. COPY の意味
  9. 7. RUN の意味
  10. 8. CMD の意味
  11. 9. ビルドして起動して確認する
  12. 10. RUN と CMD の違い
  13. 11. COPY と volumes の違い
  14. 12. 既存 Dockerfile を読む順番
  15. 13. まとめ

Docker初心者向け: compose.yml と Dockerfile の違いを最小構成で理解する で役割分担を整理し、Docker初心者向け: compose.yml の中身を1項目ずつ読む入門 で起動設定を上から読む視点を固めたあと、次に詰まりやすいのが Dockerfile 自体の読み方です。この記事では Dockerfileapp/index.php の最小 PHP サンプルを使い、FROM WORKDIR COPY RUN CMD を上から順に読みます。Dockerfile 命令の全網羅、マルチステージビルド、本番向け最適化は扱いません。

1. 記事のゴール

到達する状態:

  • Dockerfile を開いたら、どこから見始めればよいか分かる
  • FROM WORKDIR COPY RUN CMD がそれぞれ何を決めるか説明できる
  • RUNCMD の違いを build 時と起動時で整理できる
  • COPYvolumes の違いを、ローカル開発の挙動と結び付けて説明できる

扱わない内容:

  • Dockerfile 命令の全網羅
  • ENTRYPOINT ARG ENV の詳細
  • マルチステージビルド
  • 本番向けイメージ最適化

目的は、Dockerfile を全部覚えることではありません。既存リポジトリの Dockerfile を見たとき、どの行が build 時に効き、どの行が起動時の既定動作かを順番に追えるようにすることに絞ります。

2. Dockerfile は何をするファイルか

先に 1 文で置くと、Dockerfile は「イメージの中身を build 時に決めるファイル」です。

読み方も先に固定しておくと迷いにくくなります。

  1. FROM で土台のイメージを確認する
  2. WORKDIR で以後の作業場所を確認する
  3. COPY で何をイメージへ入れるかを見る
  4. RUN で build 中に何を準備するかを見る
  5. CMD でコンテナ起動時の既定コマンドを確認する

compose.yml がコンテナの起動条件をまとめるのに対して、Dockerfile はイメージをどう作るかを決めます。読むときは、上から状態が積み上がっていく前提を持つだけで整理しやすくなります。

flowchart TD
    A[FROM] --> B[WORKDIR]
    B --> C[COPY]
    C --> D[RUN]
    D --> E[image 完成]
    E --> F[CMD で起動]

3. 最小の Dockerfile を見る

今回使う構成は 2 ファイルだけです。

dockerfile-reading-demo/
├─ Dockerfile
└─ app/
   └─ index.php

作業ディレクトリを作って開きます。

mkdir -p ~/projects/dockerfile-reading-demo/app
cd ~/projects/dockerfile-reading-demo
code .

3-1. Dockerfile を作成する

FROM php:8.5-cli

WORKDIR /app

COPY app/ /app/

RUN mkdir -p /app/storage/logs

CMD ["php", "-S", "0.0.0.0:8000", "-t", "/app"]

3-2. app/index.php を作成する

<?php

declare(strict_types=1);

$logDirExists = is_dir(__DIR__ . '/storage/logs') ? 'yes' : 'no';

echo '<h1>Hello from Dockerfile</h1>';
echo '<p>PHP version: ' . PHP_VERSION . '</p>';
echo '<p>storage/logs exists: ' . $logDirExists . '</p>';

このサンプルは、5 命令の役割だけを短く追うためのものです。php:8.5-cli を土台にし、COPY でアプリを入れ、RUN で build 時の準備を行い、CMD で PHP の開発サーバを起動します。

4. FROM の意味

FROM は、どのイメージを土台にするかを決める命令です。

FROM php:8.5-cli

今回のサンプルでは php:8.5-cli を使っています。これで PHP 8.5 の CLI が入った環境が最初の土台になります。

Dockerfile を読むときに FROM を最初に確認する理由は、以後の前提がここで決まるからです。PHP のバージョン、最初から入っているコマンド、利用できるベース機能は、このイメージに依存します。

既存 Dockerfile でも、まず FROM だけ見れば「何系の環境か」の輪郭が出ます。php:8.5-cli なのか php:8.5-apache なのかで、後続の CMD や公開ポートの読み方も変わります。

5. WORKDIR の意味

WORKDIR は、それ以後の作業場所をコンテナ内のどこに置くかを決める命令です。

WORKDIR /app

今回の例では、以後の作業基準を /app に固定する形です。docker exec でコンテナに入ったときも、このディレクトリが起点になります。

WORKDIR があると、ファイル配置を読むときの基準点が定まります。今回の COPY app/ /app/ も、CMD-t /app も、すべて /app を中心に読めます。既存 Dockerfile でパスが多い場合ほど、WORKDIR を先に押さえる意味は大きくなります。

6. COPY の意味

COPY は、ホスト側のファイルを build 時にイメージへ入れる命令です。

COPY app/ /app/

この書き方では、ホストの app/ ディレクトリがイメージ内の /app/ に入ります。index.php は build が終わった時点でイメージの中に存在します。

ここで重要なのは、COPY は起動時マウントではない点です。app/index.php を変更しても、通常は docker build をやり直さない限りイメージには反映されません。

この感覚があると、「ソースを直したのにコンテナ内が変わらない」という状況を説明しやすくなります。Dockerfile の COPY は build 時の取り込みであり、起動中にホストの変更を同期する仕組みではありません。

7. RUN の意味

RUN は、イメージを build している途中でコマンドを実行する命令です。

RUN mkdir -p /app/storage/logs

今回のサンプルでは、storage/logs ディレクトリを build 時に作成する例です。index.php でこのディレクトリの有無を表示しているので、RUN の結果がイメージへ残ることを確認できます。

RUN は build 中に一度実行され、その結果がイメージに積み上がります。実務では OS パッケージの導入、PHP 拡張の追加、権限調整などにも使いますが、今回は build 時の準備だと分かりやすい最小例に絞っています。

RUN を見たら、「この Dockerfile は build 中に何を準備しているのか」を読むのが基本です。起動中に毎回実行する話ではありません。

8. CMD の意味

CMD は、コンテナ起動時の既定コマンドを決める命令です。

CMD ["php", "-S", "0.0.0.0:8000", "-t", "/app"]

今回の例では、コンテナを起動したときに PHP の開発サーバが 0.0.0.0:8000 で待ち受けるようにしています。docker run を実行すると、既定ではこのコマンドが使われます。

ここで押さえたいのは、CMD は build 時の命令ではなく、起動時の既定動作だという点です。compose.ymlcommand は、この CMD を環境ごとに上書きしたいときに使います。

9. ビルドして起動して確認する

まず、Dockerfile があるディレクトリでイメージを build します。

docker build -t dockerfile-reading-demo .

次に、コンテナを起動します。

docker run --rm -p 8080:8000 dockerfile-reading-demo

別ターミナルから表示を確認します。

curl http://localhost:8080

Hello from Dockerfile、PHP バージョン、storage/logs exists: yes が表示されれば成功です。これで COPY で入れた index.php と、RUN で作ったディレクトリ、CMD で起動した開発サーバがつながって見えます。

curl でアクセスした結果

10. RUNCMD の違い

この 2 つは混同しやすいので、build 時と起動時で分けて覚えるのが近道です。

  • RUN は image build 中に一度実行される
  • CMD は container 起動時の既定コマンドになる

今回のサンプルでは、RUN mkdir -p /app/storage/logs は build 中に終わる処理です。サーバを起動し続ける役割は持ちません。サーバを動かし続けるのは CMD ["php", "-S", ...] のほうです。

「毎回の起動で何が走るか」を見たいなら CMD を確認します。「image を作る途中で何を準備したか」を見たいなら RUN を確認します。

11. COPYvolumes の違い

ここも Docker 初学者が止まりやすい点です。

  • COPY は build 時にファイルを image へ入れる
  • volumes は起動中の container にホストのファイルを見せる

たとえば、次の compose.yml を使うとします。

services:
  app:
    build: .
    ports:
      - "8080:8000"
    volumes:
      - ./app:/app

この場合、DockerfileCOPY app/ /app/ で image に入れた内容があっても、起動時には ./app/app に bind mount されます。つまり起動後は、ホスト側の ./app/app を覆います。

この挙動を知っていると、「build で入れたはずのファイルやディレクトリが見えない」理由を追いやすくなります。Dockerfile の COPY と Compose の volumes は、同じファイル配置に見えてもタイミングが違います。

ローカル開発でソースを即反映したいなら volumes が向いています。build 済み image の中へファイルを固定したいなら COPY が向いています。両方を使うときは、後から mount する側が見え方を変えると意識すると整理しやすくなります。

12. 既存 Dockerfile を読む順番

既存の Dockerfile を読むときは、次の順で見ると迷いにくくなります。

  1. FROM で土台のイメージを確認する
  2. WORKDIR で作業基準のディレクトリを確認する
  3. COPYADD でファイル配置を確認する
  4. RUN で build 時の準備を確認する
  5. CMDENTRYPOINT で起動方法を確認する

この順番で読めば、「どこを変えると何が変わるか」の当たりが付きます。ベースイメージや拡張導入を変えるなら FROMRUN、アプリ配置なら COPY、起動方法なら CMD という切り分けです。

13. まとめ

Dockerfile は、FROM で土台を決め、WORKDIR で基準点を置き、COPY でファイルを入れ、RUN で build 時の準備を行い、最後に CMD で起動時の既定動作を決める流れで読むと整理しやすくなります。

次に読むなら、役割分担を先に整理した Docker初心者向け: compose.yml と Dockerfile の違いを最小構成で理解する、起動設定を上から読む Docker初心者向け: compose.yml の中身を1項目ずつ読む入門、または実務寄りの構成へ進む Windows 11で始めるPHPローカル開発環境(WSL2 + Docker + PostgreSQL) がつながりやすい導線です。

シリーズ 3/3

このシリーズ

Docker設定ファイルを上から読む

  1. 1. Docker初心者向け: compose.yml と Dockerfile の違いを最小構成で理解する
  2. 2. Docker初心者向け: compose.yml の中身を1項目ずつ読む入門――services / ports / volumes / environment
  3. 3. Docker初心者向け: Dockerfile の中身を上から読む――FROM / WORKDIR / COPY / RUN / CMD 現在の記事