「Dockerの使い方入門」では、Docker Hubにある既存のイメージ(hello-world、nginxなど)をそのまま使ってコンテナを起動する方法を紹介しました。今回は一歩進んで、自分のアプリケーション用に「独自のイメージ」を作るための設計図、Dockerfileの書き方を整理しておきます。
Dockerfileとは
Dockerfileは、Dockerイメージをどう組み立てるかをテキストで記述したファイルです。「どのOS・言語のイメージをベースにするか」「必要なファイルをどこに配置するか」「どんなコマンドを実行するか」といった手順を1行ずつ命令として書いていくと、その内容通りのイメージがビルドできます。既存のイメージを組み合わせるだけでは対応できない、自作のアプリケーションをコンテナ化したいときに必要になります。
よく使う基本命令
Dockerfileでは、次の命令を組み合わせてイメージを定義します。
FROM:ベースにするイメージを指定する。最初に必ず書く命令(例:FROM node:20-slim)WORKDIR:以降の命令を実行するコンテナ内の作業ディレクトリを指定するCOPY:ホスト側のファイルをイメージの中にコピーするRUN:イメージのビルド時に実行するコマンドを指定する(依存パッケージのインストールなど)ENV:コンテナ内で使う環境変数を設定するEXPOSE:コンテナが待ち受けるポート番号を明記する(ドキュメント的な意味合いが強く、実際の公開はdocker run -pで行う)CMD:コンテナ起動時に実行するデフォルトのコマンドを指定する
シンプルなDockerfileの例
Node.jsアプリケーションを例に、実際のDockerfileを見てみます。
FROM node:20-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "server.js"]
上から順に、「Node.js 20のイメージをベースにする」「作業ディレクトリを/appにする」「依存関係だけ先にコピーしてインストールする」「残りのソースコードをコピーする」「本番用の環境変数を設定する」「3000番ポートで待ち受けることを明記する」「起動時にserver.jsを実行する」という流れになっています。
ビルドとコンテナ起動
Dockerfileができたら、次のコマンドでイメージをビルドし、コンテナを起動します。
docker build -t my-app .
docker run -d -p 3000:3000 my-app
docker build -t my-app .は「カレントディレクトリのDockerfileを使って、my-appという名前でイメージをビルドする」という意味です。ビルドしたイメージは、通常のDocker Hubのイメージと同じようにdocker runでコンテナとして起動できます。
書くときに気をつけたい3つのポイント
Dockerfileを書く際は、次の点を意識すると扱いやすくなります。
- 変更頻度の低い命令を先に書く:Dockerは各命令の結果をレイヤーとしてキャッシュするため、
package.jsonだけ先にコピーしてnpm ciを実行し、その後にソースコード全体をコピーすると、依存関係が変わらない限りnpm ciのキャッシュが再利用され、ビルドが速くなります。 - .dockerignoreで不要なファイルを除外する:
node_modulesや.gitなど、イメージに含める必要のないファイルは.dockerignoreに書いておくと、ビルドが速くなり、イメージサイズも抑えられます。 - 軽量なベースイメージを選ぶ:
node:20よりnode:20-slimやnode:20-alpineのように軽量版のタグを使うと、イメージサイズが小さくなり、ビルドやデプロイの時間を短縮できます。
まとめ
Dockerfileは、自作のアプリケーションをDockerのイメージとして再現可能な形にまとめるための設計図です。FROMでベースイメージを選び、COPYやRUNで必要なファイル・処理を積み重ね、CMDで起動コマンドを指定する、という基本の流れさえ押さえれば、多くのアプリケーションはコンテナ化できます。
Dockerの基本コマンドやコンテナの起動そのものについては「Dockerの使い方入門」で、複数コンテナをまとめて管理するdocker-composeの書き方は「Dockerの使い方入門|基本コマンドとdocker-composeの書き方を実例で解説」で紹介していますので、あわせて読んでみてください。