目次
- 【Dockerfileについて】
- Dockerfileとは
- Dockerfile作成からコンテナ作成までの流れ
- Dockerfile内での処理
- 【build時に処理される命令】
- FROMコマンド
- LABELコマンド
- EXPOSEコマンド
- COPYコマンド
- RUNコマンド
- WORKDIRコマンド
- 【run時に処理される命令】
- ENTRYPOINT&CMDコマンド
- 【作成例】
- 対象のアプリ
- 作成したDockerfile
【Dockerfileについて】
Dockerfileとは
コンテナイメージを作成するための手順(コマンド)を書いたテキストファイル
Dockerfile作成からコンテナ作成までの流れ

Dockerfile作成後はbuildでイメージを作成し、runでコンテナが作成される
●buildコマンド
docker build -t <イメージ名>:<タグ(バージョン等)> <Dockerfileの場所>
●runコマンド
docker run [オプション] <イメージ名>:<タグ> <コマンド> <引数>
#よく使われるオプション(ポート公開)
-p <ポート番号(ホスト)>:<ポート番号(コンテナ)>
ポート番号はホスト側とコンテナ側で別れている
- ホスト側:外部からアクセスする用
- コンテナ側:アプリが使う用
Dockerfile内の処理
Dockerfileは、buildコマンドとrunコマンドによって以下の流れで実行されていく

- Docker Hub:Dockerイメージの置き場、FROMコマンドでダウンロードする
- レイヤー:イメージを構成する差分の積み重ね、Dockerfileの1命令ごとにレイヤーが生成される
- 中間コンテナ:一時的に作られるコンテナで、レイヤー化されたら消える
【build時に処理される命令】
レイヤーの増える処理が該当する
FROMコマンド
●内容
ベースイメージを指定してダウンロードする
Dockerfileの最初に書く
●書き方
FROM <リポジトリ名>:<タグ名>
Q. リポジトリ名とタグ名とは?
基本的にはアプリの"リポジトリ名=ランタイム","タグ名=バージョンや種類"が当てはまる
それぞれサポートされているものはDocker Hubの公式ページに一覧化されている
LABELコマンド
●内容
イメージにメタデータを登録する(入力は任意)
ユーザー情報がメインになる
●書き方
LABEL <キー>=<値>
EXPOSEコマンド
●内容
ポート番号(コンテナ側)をメタデータとして登録する
●書き方
EXPOSE <使用するポート番号>
COPYコマンド
●内容
ホスト上のファイルをコンテナ上にコピーする
●書き方
COPY <コピー元(ホスト)> <コピー先(コンテナ)>
Q. コピーすべきものと不要なもの
コピーが必要なもの
コンテナ実行時に必要なもの(例:srcフォルダ,package.jsonなど)
不要なもの
コンテナ内でインストールするもの&.gitやREADME.mdファイルなど
RUNコマンド
●内容
コンテナ内で実行されるコマンドを登録する
●書き方
# シェル形式
RUN <コマンド(引数込み)>
# EXEC形式
RUN ["<コマンド>","<引数>"]
Q. どんなコマンドを書くべきか
- イメージの生成に必要なもの
- 必要なパッケージのインストール
- 公式が指定してるもの
など
WORKDIRコマンド
●内容
コンテナ内のカレントディレクトリを指定する
●書き方
WORKDIR <パス>
【run時に処理される命令】
ENTRYPOINT&CMDコマンド
●内容
コンテナ作成時にアプリを動かすためのコマンドを登録する
2つの違いはdocker runのコマンドと引数で上書きできるか否か
- ENTRYPOINT:できない
- CMD:できる
●書き方
# シェル形式
ENTRYPOINT <コマンド(引数込み)>
CMD <コマンド(引数込み)>
# EXEC形式
ENTRYPOINT ["<コマンド>","<引数>"]
CMD ["<コマンド>","<引数>"]
【作成例】
サンプルアプリ用にDockerfileを作成
対象のアプリ
ランタイム:Node.js(v20系)
フレームワーク:Express
必要なライブラリ:npmのみ
作成したDockerfile
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3001
CMD ["node", "app.js"]
Q. COPYコマンドを2回入れている理由
Dockerは各命令ごとにキャッシュを持っており、命令内容や参照するファイルに変更がなければ再実行されずキャッシュが利用される。逆に変更があった場合、その命令以降は再実行される。
今回はpackage*.jsonを先にコピーすることで、依存関係に変更がない限りnpm installが再実行されないようにしている。これによりソースコードのみ変更した場合のビルド時間を短縮できる。