【Docker】Dockerfileの書き方基本

Docker

こんにちは、かつコーチです。

docker pull で公式イメージを使うだけなら簡単なのですが、自分のアプリケーション用のイメージを作ろうとすると、多くの人が最初につまずくのがDockerfileです。

「命令がたくさんあってどれから書けばいいかわからない」「書いたはいいけどビルドが通らない」という声をよく聞きます。

この記事では、Dockerfileとは何かという基本の考え方から、最小構成のDockerfileを実際に書いてビルドするところまでを、手順に沿って解説します。

Linux基礎編・シェルスクリプト編、そしてDockerの基本操作(run・ps・images)は理解している前提で進めます。

Dockerfileとは?

レシピに例えると分かりやすい

Dockerfile(イメージの作り方を記述したテキストファイルです)は、料理でいうレシピに例えるとイメージしやすいです。

レシピには「材料はこれを使う」「この順番で調理する」という手順が書かれています。

Dockerfileも同じで、「どのOS・言語環境をベースにするか」「どのファイルを配置するか」「起動時に何を実行するか」という手順を順番に記述します。

このレシピ(Dockerfile)を元に docker build すると、完成品であるイメージ(コンテナの設計図)が出来上がります。

なぜDockerfileが必要なのか

イメージは docker commit でコンテナから直接作ることもできます。

ただしこの方法だと、「どんな手順でそのイメージができたのか」が誰にもわからなくなってしまいます。

Dockerfileにテキストとして手順を残しておけば、Gitで管理できますし、同僚が同じ環境を再現することも、半年後の自分が「なぜこの設定にしたか」を思い出すことも簡単になります。

再現性と共有のしやすさこそが、Dockerfileを使う一番の理由です。

基本の書き方・実装手順

最小構成のDockerfileを書いてみる

まずは、Node.jsのアプリケーションを動かす最小構成のDockerfileを見てみましょう。

# Dockerfile
FROM node:20-slim

WORKDIR /app

COPY package.json .
RUN npm install

COPY . .

CMD ["node", "index.js"]

上から順に「ベースイメージを指定する」「作業ディレクトリを決める」「必要なファイルを配置してコマンドを実行する」「起動時のコマンドを決める」という流れになっています。

各命令の詳しい役割は次回の記事で扱うので、ここでは「上から順番に実行される手順書」というイメージだけ持っておいてください。

ビルドしてイメージを作る(docker build)

Dockerfileを書いたら、同じディレクトリで以下を実行します。

docker build -t my-node-app:1.0 .

-t オプションでイメージに名前とタグを付け、末尾の . でビルドコンテキスト(Dockerfileや関連ファイルが置かれているディレクトリ)を指定します。

ビルドが完了したら、docker images で作成されたイメージが確認できます。

docker images

つまずきやすい設定・注意点

Dockerfileを書くときは、.dockerignore(イメージに含めたくないファイルを指定する設定ファイルです)も一緒に用意しておくことをおすすめします。

# .dockerignore
node_modules
.git
*.log

.gitignore に似た書き方で、node_modules のような巨大なディレクトリや、.git のような不要なファイルをビルドコンテキストから除外できます。

これを忘れると、ビルドコンテキストの送信に時間がかかったり、意図しないファイルがイメージに混入したりします。

よくあるつまずきポイント・エラー対処

COPYの順序でキャッシュが毎回効かない

実際に私が経験したつまずきが、Dockerfileの命令順序によるビルド時間の問題です。

❌ Before:ソースコード全体を先にコピーしてしまう

FROM node:20-slim
WORKDIR /app

COPY . .
RUN npm install

CMD ["node", "index.js"]

このDockerfileだと、ソースコードを1行変更するだけで COPY . . の内容が変わったと判定され、そこから下の RUN npm install のキャッシュがすべて無効化されます。

私は最初これに気づかず、コードを1行直すたびに npm install が毎回1分以上かかる状態で作業していて、「Dockerのビルドって遅いものなんだ」と誤解していました。

✅ After:依存関係のインストールとソースコードのコピーを分ける

FROM node:20-slim
WORKDIR /app

COPY package.json .
RUN npm install

COPY . .

CMD ["node", "index.js"]

package.json を先にコピーして npm install を済ませておけば、package.json に変更がない限り、この2行分のキャッシュが再利用されます。

ソースコードだけを直した場合は、COPY . . 以降だけが再実行されるので、ビルド時間が数秒まで短縮できました。

応用・一歩先の使い方

レイヤーキャッシュを意識した命令順序

Dockerfileの各命令はレイヤー(変更の少ないものを上に、変更の多いものを下に書くほどキャッシュが効きやすくなります)として積み重なります。

基本の考え方は「変更頻度が低いものを上、高いものを下」です。

  • OS・ランタイムのバージョン(FROM)はほぼ変わらない → 一番上
  • 依存関係の定義ファイル(package.json など)はたまに変わる → 中間
  • ソースコードは頻繁に変わる → 一番下

この順序を意識するだけで、日々の開発でのビルド待ち時間を大きく減らせます。

まとめ

この記事のポイント

  • Dockerfileはイメージを作るための手順書で、レシピに例えると理解しやすい
  • docker build -t 名前:タグ . でDockerfileからイメージをビルドする
  • .dockerignore で不要なファイルをビルドコンテキストから除外する
  • 変更頻度の低いものを上、高いものを下に書くとキャッシュが効いてビルドが速くなる

次に読むべき記事

  • よく使うDockerfile命令(FROM・COPY・RUN・CMD)
  • マルチステージビルドでイメージを軽量化する

タグ: Docker, 中級者向け, Dockerfile

タイトルとURLをコピーしました