UdemyのDocker講座をやり始めた
https://techblog.jasmine-s.com/chanchanrk-20200901-374
この続きです。
Dockerfileの書き方について学習しました。
DockerHubから、MySQLのDockerfileを元に説明してみます。
現時点のlatestのDockerfileです。
https://github.com/docker-library/mysql/blob/285fd39122e4b04fbe18e464deb72977df9c6a45/8.0/Dockerfile
Dockerfileで使われる主な命令
FROM
ベースとなるdockerイメージを指定します。
MySQLではdebianというLinuxがベースになっています。
FROM debian:buster-slim
RUN
dockerイメージに対して実行するコマンドを記述します。
MySQLではこのように記述されています。
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
RUNではapt-getを一行で書く
RUN apt-get update
RUN apt-get install -y [パッケージ名]
とRUNを分けても同じ結果になるのですが、RUNを何度も書くとその分だけdockerイメージが大きくなってしまいます。
RUNの数だけdocker buildした時にビルドのステップが増え、dockerイメージのサイズも大きくなります。
dockerイメージが大きくなるとそれだけディスク容量を使うことになり使いにくくなるため、
apt-get update && apt-get install -y [パッケージ名]
このように一度のRUNでなるべく多くのコマンドを実行するのがDockerfileを書くコツだそうです。
apt-get installのオプション
-yオプションはインストール中の確認メッセージに対しyesで自動的に回答するために付けます。
--no-install-recommendsオプションは推奨される余分なパッケージが同時にインストールされないように付けます。
ENV
ENV GOSU_VERSION 1.12
https://github.com/docker-library/mysql/blob/285fd39122e4b04fbe18e464deb72977df9c6a45/8.0/Dockerfile#L10
環境変数を定義します。
ENVで環境変数を1つ定義する場合
ENV key value
ENVで複数の環境変数を定義する場合
ENV key1=value1 key2=value2
このように書くと複数の環境変数を定義できます。
複数の環境変数を書く場合で、値に空白を含める場合は""で囲むか、\でエスケープします。
ENTRYPOINT CMD
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
https://github.com/docker-library/mysql/blob/285fd39122e4b04fbe18e464deb72977df9c6a45/8.0/Dockerfile#L82-L85
ENTRYPOINTはdockerイメージをrunした時に自動的に実行されるコマンドを指定します。
CMDは、ENTRYPOINTで実行されるコマンドのオプションになります。
上記の場合ですと、
docker-entrypoint.sh mysqld
というコマンドが実行されるという意味になります。
ENTRYPOINTが無く、CMDのみの場合
CMD行に実行するコマンドとオプションを両方とも指定します。
lsコマンドで-laオプションを付ける場合はこのように指定します。
CMD ["ls","-la"]
CMDはdocker runする時に上書きできる
dockerイメージを実行する時にはdocker runコマンド使います。
docker run -it [イメージの名前またはID]
この時に、[イメージの名前またはID]の後に記述をすることでCMDを上書きできます。
docker run -it [イメージの名前またはID] /bin/bash
CMDはENTRYPOINTがあるかないかによって意味が変わるため上書きの意味も変わります。
ENTRYPOINTがある→docker run時にENTRYPOINTのコマンドのオプションを上書きできる
ENTRYPOINTがない→docker run時にコマンドとオプションを上書きできる
COPY
COPY config/ /etc/mysql/
https://github.com/docker-library/mysql/blob/285fd39122e4b04fbe18e464deb72977df9c6a45/8.0/Dockerfile#L79
dockerコンテキスト(dockerのビルドに必要なファイルが置かれているディレクトリ)から、
dockerイメージ内に配置したいファイルをコピーします。
ADD
COPYと似ていますが、tarアーカイブファイルを展開してくれる機能があります。
サイズの大きなファイルを圧縮しておいて、dockerイメージのビルド時に展開する目的で使われるケースがほとんどだそうです。
WORKDIR
COPYやADDなどで、dockerイメージ内でファイル操作をする場合に、作業ディレクトリを移動することがあります。
RUNでcdコマンドを実行してもディレクトリを移動できますが、RUNを跨ぐとディレクトリ場所がルートディレクトリの/に戻ってしまいます。
WORKDIRで作業ディレクトリを指定しておくとその後のRUNをすべて指定したディレクトリ上で行うことができるため、
RUNでcdコマンドを実行するよりも、WORKDIRで指定した方がより良いです。
WORKDIRで指定したディレクトリは存在しなければ自動的に作成されます。
まとめ
今回は以上です。
Dockerfileの書き方について学習しましたが、ベースとなるイメージにたいして継ぎ足していくという感じですので、
まずは使ってみて徐々に改善していくという使い方が良さそうです。