3秒でわかる
コンテナイメージの作り方を一行ずつ書いた手順書。同じ環境をどのマシンでも再現するために、土台の指定から依存の導入、起動コマンドまでを記述します。
もう少し詳しく
どういうものか
Dockerfile は、コンテナイメージを組み立てる手順を上から順に書いたテキストファイルです。docker build がこの一行ずつを実行し、各命令の結果をレイヤーとして積み重ねて一つのイメージにします。土台となるイメージを FROM で選び、COPY でファイルを入れ、RUN でコマンドを実行し、CMD で起動時に走らせるコマンドを決める、というのが基本の流れです。
なぜ必要か
環境構築の手順が手順書やチャットに散らばっていると、人によって導入したライブラリの版が変わり、「自分の環境では動く」という状態が生まれます。Dockerfile は手順そのものをコードとしてリポジトリに置くので、誰が実行しても同じ環境が出来上がります。本番へ持っていくものが手順ではなく完成品のイメージになるため、本番だけ違う、という差も生まれにくくなります。
具体例
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-slim
WORKDIR /app
ENV NODE_ENV=production
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]package*.json だけを先にコピーして npm ci を走らせているのは、依存が変わっていない限りその層のキャッシュが効き、ビルドが数秒で済むようにするためです。ソースを先にコピーすると、一文字直しただけで依存の導入からやり直しになります。
つまずきやすいところ
RUN を細かく分けるとレイヤーが増えてイメージが膨らみます。apt でパッケージを入れる場合は、更新と導入とキャッシュ削除を && でつないで一つの RUN にまとめるのが定石です。また、途中の RUN で削除したファイルも前の層には残っているため、秘密情報を一度コピーしてから消しても、イメージからは取り出せてしまいます。鍵やトークンは COPY せず、実行時の環境変数やシークレット機能で渡します。
CMD と ENTRYPOINT の使い分けも迷いどころで、実行するプログラムを固定したいなら ENTRYPOINT、既定の引数として上書きされてよいものは CMD に置きます。
覚え方
Dockerfile は「新しいパソコンに環境を作るときの手順書を、そのまま実行できる形にしたもの」と捉えると、書く順番も決めやすくなります。変わりにくいもの(土台のイメージ、OS のパッケージ、依存ライブラリ)を上に、変わりやすいもの(自分が書いたソース)を下に置く。この並びがキャッシュの効き方をそのまま決めます。