🐳

【Docker】Dockerfileについてまとめました。

2022/02/14に公開

Dockerfileとは

  • Dockerfileとは、Dockerイメージを作成するための設定が書かれたファイルです。
  • Dockerfileをビルドすることで、Dockerイメージを作成することができます。
// dockerfileをビルドして、Dockerイメージを作成
docker build -t 作成するイメージ名 Dockerfileがあるフォルダのパス

Dockerfileを使わないと、どうなる?

  • Dockerfileを使わずにDockerイメージを共有した場合、ベースイメージにどのような変更を加えたのかがわからず(コードで管理していないので見えない)修正も困難といった問題があります。

Dockerfileを使って上記問題を解決

  • Dockerfileを使うことで、上記問題を解決することができます。
  • さらに下記のメリットがあります。

構築手順をコードとしてファイルに残せる

  • 変更点がコードとして可視化される為、修正が簡単です。

簡単に共有できる

  • テキストファイルなので軽いです。

Gitでバージョン管理ができる

  • コードで管理することで実現可能になります。

Dockerfileの特徴

  • Dockerfileには下記の特徴があります。

レイヤ構造

  • Dockerfileを書く際にはまず、FROM命令でベースとなるイメージを指定します。
  • それに続いて、アプリのインストールやホストからコンテナ内のファイルシステムへのファイルの追加などの変更を加えていきます。
  • このようにコンテナは「変更差分(レイヤ)の集まり」としてみなされます。

  • 作成されたファイルイメージから実行されるコンテナは初め、実行環境中のファイルシステムに何も格納されていない状態です。
  • これに変更差分を加えていき、結果として得られるファイル群をルートファイルシステムとしてコンテナは実行されます。
  • Dockerfileの命令コマンドの数だけ、Dockerイメージのレイヤが増えていきます。
  • そして、このレイヤが増えていくと、Dockerイメージのサイズもどんどん大きくなってしまうので、できるだけDockerイメージを軽くしておくためにも、「まとめられるコマンドはまとめる」事を意識します。
// 悪い例
RUN yum install -y hoge
RUN yum install -y fuga
// 良い例
RUN yum install -y hoge fuga
  • ただし、頻繁に変更が発生しそうなコマンドは、あえてまとめずに分けておくことも大切です。
  • また、変更が頻繁にされるファイルは、Dockerfileの下に記述することが推奨されます。
    • 次項目のキャッシュで説明します。

キャッシュ

  • Dockerビルドをした際に、レイヤが「キャッシュ」されるという特徴があります。
  • 一度ビルドしたDockerイメージのレイヤは、キャッシュしているため、実行時間や実行ログが短縮されます。
  • ただし、Dockerfileに新たな命令コマンドを追加すると、その追加した行から下の命令はキャッシュされません。
  • ビルド時間を短縮するためにも、変更が少ないコマンドはDockerfileの上のほうに、変更頻度が高そうなコマンドは下のほうに書くようにします。
  • キャッシュをクリアしたい時は、下記コマンドでクリアできます。
// キャッシュを削除
$ docker builder prune

Dockerfileで使用するコマンド

FROM

  • ベースとなるイメージを指定します。
  • Dockerfileの最初に記述します。
FROM [--platform=<プラットフォーム>] <イメージ名> [AS <名前>]
FROM [--platform=<プラットフォーム>] <イメージ名>[:<タグ>] [AS <名前>]
FROM [--platform=<プラットフォーム>] <イメージ名>[@<ダイジェスト>] [AS <名前>]

RUN

  • イメージをビルドする際のコマンドを指定します。
// シェル形式(コマンドはシェル内で実行される)
RUN <コマンド>
// 実行形式
RUN ["実行ファイル", "パラメータ1", "パラメータ2"]

CMD

  • コンテナ起動時に実行するコマンドとオプションを設定します。
  • CMD 命令は Dockerfile 中で1度しか使えません。
  • 複数の CMD 命令があれば、最後の CMD のみ有効です。
CMD ["実行ファイル","パラメータ1","パラメータ2"]
CMD ["パラメータ1", "パラメータ2"]
CMD コマンド パラメータ1 パラメータ2 

ENV

  • Dockerfileの中で利用する環境変数を設定するための命令コマンドです。
  • CPで指定するファイルパスなど、何度も繰り返し出てくるような場合は設定します。
ENV <キー>=<値> ...

COPY

  • ホストマシンにあるファイルやディレクトリを、コンテナにコピーします。
  • NginxやApacheなどの設定ファイルをコピーする際に利用します。
COPY [--chown=<ユーザ>:<グループ>] <コピー元>... <コピー先>
COPY [--chown=<ユーザ>:<グループ>] ["<コピー元>",... "<コピー先>"]

ADD

  • ホストマシンにあるファイルやディレクトリを、コンテナにコピーし展開(解凍)します。
  • ホストマシンにある圧縮ファイルの「コピー」と「展開」を同時におこないたい場合に便利です。
ADD [--chown=<ユーザ>:<グループ>] <追加元>... <追加先>
ADD [--chown=<ユーザ>:<グループ>] ["<追加元>",... "<追加先>"]

WORKDIR

  • RUNやADDなどの命令コマンドを実行するディレクトリを設定します。
  • ディレクトリがない場合は自動で作成してくれるため、ディレクトリ作成と移動を同時にしたい場合にも使います。
  • 特定のディレクトリで命令コマンドを実行することが多い場合は、設定するようにしましょう。
WORKDIR パス

LABEL

  • イメージに メタデータ(名前、バージョン番号、製作者情報)を追加します。
LABEL <キー>=<値> <キー>=<値> <キー>=<値> ...

EXPOSE

  • コンテナの実行時、指定した ネットワーク・ポートをコンテナがリッスンするように、Dockerへ通知します。
  • 対象ポートがTCPかUDPか、どちらをリッスンするか指定できます。
  • プロトコルの指定がなければ、TCPがデフォルトで設定されます。
EXPOSE <ポート> [<ポート>/<プロトコル>...]

VOLUME

  • 永続データが保存される場所を指定します。
VOLUME ["/data"]

HEALTHCHECK

  • コンテナの死活確認をするヘルスチェックの方法をカスタマイズします。
// コンテナ内部でコマンドを実行し、コンテナの正常性を確認
HEALTHCHECK [オプション] CMD コマンド
// ベースイメージから、ヘルスチェック設定の継承を無効化
HEALTHCHECK NONE

ONBUILD

  • ビルドが完了した際に、任意の命令を実行します。
ONBUILD [命令]

ARG

  • docker buildする際に、指定できる引数を宣言できます。
ARG <名前>[=<デフォルト値>]

STOPSIGNAL

  • docker stopする際に、コンテナで実行しているプログラムに対して送信するシグナルを変更する
STOPSIGNAL 信号

SHELL

  • ビルドした際に使うシェルを指定します。
SHELL ["実行ファイル", "パラメータ"]

まとめ

Dockerfileについてまとめてみました。
使ったことがないコマンドが沢山あったので、実際に使ってみたいです。
最後まで閲覧いただき、ありがとうございました!

Discussion