自主的20%るぅる

各々が自主的に好き勝手書くゆるふわ会社ブログ

Dockerfile

Dockerfileを解説

コンテナの基礎から学んでECS、EKSを学んでいこうと思い、Docker/Kubernetes実践コンテナ開発入門 (改訂新版)を読んでいたのですが、今回はDockerfileの記述内容の意味を整理するために執筆しました。

本記事ではコンテナとは?という点については焦点を当てておりませんので、その点については割愛させていただきます。

そもそもDockerfileとは

DockerfileとはDockerイメージを作成するためのいわば設計書のようなものです。

コンテナを作成するためには、そのコンテナのイメージが必要になりますが、イメージを作成するためにはコードを記述し、Dockerfileを作成する必要があります。

Dockerfileにはどんなことを記述するの?

Dockerfileに記述する内容は以下のようなものです。

※以下コードはDocker/Kubernetes実践コンテナ開発入門 (改訂新版)から引用させていただきました。

Dockerfile

  • FROM
  • WORKDIR
  • RUN
  • ENV
  • COPY
  • CMD

上記について順番に説明していきましょう。

FROM

まずFROMですが、こちらはコンテナのベースとなるイメージを指定します。

ベースとなるイメージとは、OSであればLinuxのディストリビューションを例にお話しさせていただきますと、

Ubuntu、CentOS、AWSであればAmazon Linuxなどが存在しますが、これらのベースをどれにしますか?を決める箇所です。

OS以外でも例えばプログラミング言語のベースイメージはどれにする?といった場合、PHPなのか、GoなのかをFROMで指定してやることで、そのベースのイメージを作成することができます。

本記事の例ではubuntu:23.10と指定していますが、イメージにubuntuを指定し、「:」よりも後ろの数字はタグを指定します。

「タグ」とは言いますが、指定したイメージのバージョンを表しています。ubuntuにもバージョンがありますが、23.10のバージョンを使いますよ、ということを明示的に指定しています。

このタグを指定しない場合は「latest」となります。

もっと一般的な例に置き換えるならば、「Finalfantasy:7 REBIRTH」というイメージにした場合、ベースとなるイメージは「Finalfantasy」,タグ(バージョン)は「7 REBIRTH」のイメージを作る感じです。

WORKDIR

コード内には出てきていませんが、WORKDIRに指定する内容は後述するRUN, COPY, CMDなどの命令する実行するコンテナのディレクトリの場所を指定することになります。

例えばWORKDIR /appであれば、コンテナ内の/appディレクトリでコマンドを実行する、/appディレクトリにコピーする、ために指定します。

またコンテナ内に/appディレクトリが存在しない場合はどうか?という話ですが、その場合には/appディレクトリを新規で作成してくれます。

RUN

次にRUNです。今回示した例ではRUNを以下のように指定しています。

RUN apt update
RUN apt install -y cron

このRUNはDockerのイメージをビルドする際に、コンテナ内で実行するコマンドを定義します。
Dockerイメージをビルドとは、ビルドする際にDockerfileのコードの内容を上から順に読み取ってDockerイメージを作り上げていくわけですが、その際にRUNにコマンドの内容が記述されている場合にはそのコマンドが実行されたイメージが出来上がります。

そのためコンテナを起動する際には、すでにRUNに記述された状態のイメージを起動するわけなので、docker run などでコンテナを起動したときには既にRUNは実行されています。

順番としては以下でしょう。

  1. $ dockder image build コマンドでDockerイメージがビルドされる
  2. そのビルドの過程でRUNに記述された内容が実行される
  3. コンテナをイメージから起動する際には、すでにRUNに記述されたコマンドが実行された状態のものが起動される

Dockerfile

ENV

ENVは環境変数を指定します。

MySQLを例に話をします。MySQLのイメージを作成する際には環境変数を渡すことでMySQLの値を設定することができます。

MySQLにおける環境変数とは例えば以下のようなものです。

  • MYSQL_ROOT_PASSWORD
  • MYSQL_DATADASE
MYSQL_ROOT_PASSWORD

MySQLのrootアカウントに設定するパスワードを指定します。

MYSQL_DATABASE

データベースの名前を指定します。

これらをDockerfileに記述する場合は以下のようになります。

ENV MYSQL_ROOT_PASSWORD
ENV MYSQL_DATABASE

はい、ここで気づいた方もいるかと思いますが、厳密にはENVに環境変数の値を直接は書きません。

外部ファイルに環境変数を定義してファイルを渡す、などの手法が用いられます。

※ここら辺の詳細はdocker-compose.ymlの関する内容を今後ブログでアウトプットできればと思っております。

COPY

ビルドコンテキストのファイルやディレクトリをコンテナ内にコピーします。

COPY task.sh /usr/local/bin/

指定の仕方はCOPY [コピー元] [コピー先] となります。

上記の例だと、task.shをコンテナ内の/usr/local/bin/へコピーする、という意味になります。

 

ビルドコンテキストとは

docker buildコマンドを実行する際に付与する情報のことを指します。

「ファイルlocationのセット」とも表現することができますが、Dockerfile以外にも同じディレクトリ内にファイルが存在する場合にはファイルlocationのセットの一部であり、それらが「ビルドコンテキスト」になります。

参考:docker build | Docker Docs

 

実際にディレクトリ構成を見ながら説明します。

現状のディレクトリ構成は以下のようになっています。

work
└─ ch03
           └─cronjob
                    ├─ Dockerfile
                    └─ task.sh

cronjob配下にDockerfileとtask.shが存在します。task.shがビルドコンテキストとなります。

上記の例ではtask.shのファイルのみしか存在しませんが、ディレクトリを指定すれば、そのディレクトリに存在するファイルすべてがビルドコンテキストということになります。

CMD

RUNはイメージビルド時に実行されるコマンドと説明しましたが、CMDはイメージビルド後にコンテナ起動時に実行します。

CMDの書き方は配列形式で指定をします。

CMD ["cron", "-f"]

上記コマンドがどのように実行されているかというと、以下のコマンドがコンテナ内で実行されます。

$ cron -f

最後に

Dockerfileの内容はなんとなくはわかっていましたが、深堀りすると人に説明できるほどの理解度がなかったため、今回ブログにまとめました。

まだまだ序の口なので今後もDockerに関しての知見を広げていくためにアウトプットしていこうと思っています。

Let’s share this article!

{ 関連記事 }

{ この記事を書いた人 }

アバター画像
Yuki_Izumi

32歳から医療業界からエンジニアに転職しました。

野球、バスケ、将棋、絵を描くこと、などなど
色々多趣味ですが、結婚してエンジニアになってからは
すべて疎遠になりました。

生活に余裕ができたらすこーしずつ趣味も実践していきたいと
思っている未熟エンジニアです。

記事一覧