Dockerfileとは?
Dockerfileの命令
https://docs.docker.jp/engine/reference/builder.html
より基本的な命令を抜粋します。
FROM | ベースイメージを指定する |
ENV | イメージのOSに環境変数を定義する |
ARG | docker buildコマンドから受け取るパラメータを定義する |
WORKDIR | イメージOS内での作業ディレクトリを指定する |
ADD | リモートのファイルをイメージに追加する |
COPY | ホストのファイルをイメージにコピーする |
RUM | イメージ上で任意のコマンドを実行する |
CMD | コンテナ起動時に実行するコマンドを定義する (上書き可能) |
ENTRYPOINT | コンテナ起動時に必ず実行するコマンドを定義する |
VOLUME | ホストのディスクをコンテナにマウントする |
EXPOSE | ポートをコンテナ外部に公開する |
FROM ベースイメージを指定する
- 可能ならalpineという名前のついたイメージの使用が推奨されている。
- alpineは最小構成のイメージで、要領が小さいLinuxディストリビューションである。
ENV イメージのOSに環境変数を定義する
DockerfileのENV命令を使用すると、イメージのOSに環境変数を定義できます。
ENVにより設定された環境変数は、コンテナでも維持されます。
FROM openjdk:11
ENV HOGE="hoge!"
$ docker build -t hoge .
[+] Building 1.0s (5/5) FINISHED
... 0.0s
$ docker run -dit hoge:latest
b46eafc00b2eae9a8e3102a7e7f5ed8b2c3d73a4bc777abda3893d85b7d84630
$ docker exec -it b46eafc00b2eae9a8e3102a7e7f5ed8b2c3d73a4bc777abda3893d85b7d84630 /bin/sh
# echo $HOGE
hoge!
ARG docker buildコマンドから受け取るパラメータを定義する
DockerfileのARG命令を使用すると、docker build中のみ適用されるパラメータを宣言できます。
すなわち、Dockerfile内で有効なパラメータを受け取るために使います。
FROM openjdk:11
ARG DIR_NAME=hoge
RUN mkdir /${DIR_NAME}
DIR_NAME をdocker buildのパラメータとして受け取れるようにしました。
パラメータが指定されていない場合は、"hoge"がデフォルト値になります。
// イメージ作成
$ docker build -t hoge . --build-arg DIR_NAME=hogehoge
[+] Building 1.4s (6/6) FINISHED
...
$ docker run -dit hoge:latest
484834407f817755b4f6f3763ff767165d61c343956efb11655773b3406407c0
// コンテナ起動
$ docker exec -it 484834407f817755b4f6f3763ff767165d61c343956efb11655773b3406407c0 /bin/sh
// 確認
# ls /
bin dev hogehoge lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr
イメージ作成時の「--build-arg DIR_NAME=hogehoge」でDIR_NAMEにパラメータを渡しています。
それによって、/hogehogeが作成されています。
WORKDIR イメージOS内での作業ディレクトリを指定する
DockerfileのWORKDIR命令を使用すると、以降の命令の作業ディレクトリを指定できます。
WORKDIRはホストの作業ディレクトリではなく、イメージ内のディレクトリです。
FROM openjdk:11
RUN ["mkdir", "/hoge"]
WORKDIR /hoge
RUN ["mkdir", "fuga"]
2行目で /hoge を作成する。
3行目で /hoge に移動する。
4行目でfugaを作成する。
$ docker build -t hoge .
[+] Building 2.4s (9/9) FINISHED
...
$ docker run -dit hoge:latest
744b96ba5102bf3288907f7a6637ed64a714f12226271f213455bd0acaab0c70
$ docker exec -it 744b96ba5102bf3288907f7a6637ed64a714f12226271f213455bd0acaab0c70 /bin/sh
# ls /
bin dev hoge lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr
# ls /hoge
fuga
/hoge
/hoge/fuga
が作成されていることから、作業ディレクトリが移動できたことがわかります。
ADD リモートのファイルをイメージに追加する
FROM openjdk:11
RUN ["mkdir", "/hoge"]
ADD ./test.txt /hoge
// コピーするファイルを作成
$ echo "heeeeii" > test.txt
$ ls
Dockerfile test.txt
// イメージをビルド
$ docker build -t hoge .
[+] Building 2.0s (9/9) FINISHED
...
$ docker run -dit hoge:latest
45a5b5770b975058a16648a2e3f987ffd55236b39758f6ccf54a19bad2093ae9
// 確認
$ docker exec -it 45a5b5770b975058a16648a2e3f987ffd55236b39758f6ccf54a19bad2093ae9 /bin/sh
# ls /
bin dev hoge lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr
# ls hoge
test.txt
# cat /hoge/test.txt
heeeeii
DockerfileのADDとCOPYの違い
ADD
- リモートからもファイル追加できる
- 圧縮ファイルが自動解凍される
COPY
- リモートからのファイル追加は出来ない
- 圧縮ファイルは自動解凍されない
基本的にはCOPYを使うべきです。
ADDはリモートからファイルをダウンロードして、イメージに加える場合に使用します。
COPY ホストのファイルをイメージにコピーする
FROM openjdk:11
RUN ["mkdir", "/hoge"]
COPY ./copy.txt /hoge
// コピーするファイルを確認
$ ls
Dockerfile copy.txt
$ cat copy.txt
this is copy
// イメージをビルド
$ docker build -t hoge .
[+] Building 2.7s (10/10) FINISHED
...
$ docker run -dit hoge:latest
3d85fb490a95fdd52387caf8b2dca5f2c21a631f92941e9cc482efdab9bea323
// 確認
$ docker exec -it 3d85fb490a95fdd52387caf8b2dca5f2c21a631f92941e9cc482efdab9bea323 /bin/sh
# ls
bin dev hoge lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr
# cat /hoge/copy.txt
this is copy
RUN イメージ上で任意のコマンドを実行する
DockerfileでRUN命令を使用すると、イメージをビルドする過程で任意のコマンドを実行できます。
FROM openjdk:11
RUN ["mkdir", "/hoge"]
$ docker build -t hoge .
[+] Building 2.9s (7/7) FINISHED
... 0.0s
$ docker run -dit hoge:latest
1ecfc8af8c8f87f7db2cf1ca6086fe8ab9aa5b60b0288ef22db1aa2293bc4941
$ docker exec -it 1ecfc8af8c8f87f7db2cf1ca6086fe8ab9aa5b60b0288ef22db1aa2293bc4941 /bin/sh
# ls /
bin dev hoge lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr
コンテナのルートディレクトリにhogeが作成されています。
RUN
において一番利用する使い方が apt-get
アプリケーションの実行である。
apt-getを使用してパッケージをインストールする場合は、次のように記述するのが推奨される。
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo
VOLUME ホストのディスクをコンテナにマウントする
コンテナで生成されるデータ(DBのデータなど)をコンテナが停止後も利用するために使います。
EXPOSE ポートをコンテナ外部に公開する
EXPOSE 8080
DockerfileにEXPOSE ポート番号と書くことで、ポートをコンテナ外部に公開できます。
これにより、ホストのブラウザからコンテナにアクセスできるようになります。
このことは、Dockerdesktopを見るとわかりやすいです。
Imagesの任意のイメージからコンテナを起動するため、RUNを押します。
すると、Optional Settingが選択できますので、その画面を見比べてみます。
EXPOSE 8080
EXPOSE なし
このように、ホストの任意のポートを、コンテナがEXPOSEしているポートに振り分けるようにすることができるようになります。
Dockerfileのベストプラクティス
http://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html
より主要なプラクティスを抜粋します。
レイヤの数を最小に
RUN、COPY、ADD命令はレイヤを作成する。
レイヤを作成すると、イメージの要領が増えるため、そられの命令使用回数は少ない方が良い。
良くない
RUN apt-get update
RUN apt-get install -y bzr
RUN apt-get install -y git
良い
RUN apt-get update && apt-get install -y bzr \
git