Dockerfileの書き方と使い方



Dockerfileの書き方と使い方

AWSで Dockerコンテナを運用しようとしたり、 DockerでRailsを起動しようとした時に Dockerfile は必要。

こちらでは Dokcerfile の基本的な書き方や起動方法、確認方法をご紹介させて頂きます。

目次
  1. Dockerfileの書き方と使い方と確認方法
  2. Dockerfileとは
  3. Dockerfileのコードリスト
  4. Dockerfileを作る・使う様子の動画
  5. Dockerfile① Apacheサーバーのインストール
  6. Dockerfile② ファイルのコピー
  7. Dockerfile③ git clone
  8. Dockerfile④Volumeの設定
  9. Volumeセット
  10. まとめ

Dockerfileの書き方と使い方と確認方法

Dockerfileとは

画像クリックで拡大

Dockerfileは、Dockerのイメージを自動で作成してくれるファイル。 docker build . と入力するだけで、 Dockerシステムは Dockerfileを自動で読み込み、書かれている内容の通りの Dockerイメージを作成してくれます。

Dockerfileの内容としては、上図のような Docker特有の書き方。 普通アプリケーションの開発環境を整える際は、OS 内のコマンドで必要なソフト、例えば Apache や git、 Vim などをインストールすると思いますが、Dockerfileを使うとそうした一連の作業を自動で行うことが可能に。

この結果、開発環境の構築にかかる時間を大幅に短縮化し、 誰が行なっても同じ開発環境を作ることができるように。そして各ソフトウェアのバージョン相違等の環境ミスもなくせる、というメリットがあるという訳。

画像クリックで拡大

また Dockerfile は単に均一の Docker イメージを作成できる、というだけでなく、上図に示すような活用方法も。

  • コンテナのベースに
  • Docker Hub への公開に
  • AWS等への活用に
  • イメージの機能拡張、継承に

コンテナのベースや Docker Hubへの公開については、 Dockerfile に限った機能ではありません。 Docker のイメージが作成できる、 docker commit でも同じでしょう。

「AWS等への活用」については、Dockerのコンテナベースで運用できる AWS や Azure などで、 Dockerfile が必要に。そしてイメージの機能拡張や継承については、 Docker のイメージを元に機能を追加したい時に便利。今回ご紹介する Dockerfile も Ubuntuイメージに Apache機能を追加していますし、 以下のような WordPressのイメージにキャッシュ機能を追加するという応用方法も。

【Dockerイメージの WordPress にキャッシュ機能を追加したDockerイメージ】

画像クリックで拡大

Dokcer Hub/oshimamasara

このように Dockerfile が使えるようになると、Dockerを用いたアプリ開発の効率が上がりそうというもの。 それでは次に Dockerfile の公式ドキュメントを元に、 Dockerfile の基本的な機能を確認しておきたいと思います。

Dockerfileのコードリスト

Dockerfileで使う命令コード(オレンジマークは今回使用するもの)
FROM ベース(親)画像を指定します。
LABEL メタデータを提供します。 メンテナ情報を含めるのに良い場所です。
ENV 永続的な環境変数を設定します。
RUN コマンドを実行してイメージレイヤを作成します。 パッケージをコンテナにインストールするために使用されます。
COPY ファイルとディレクトリをコンテナにコピーします。
ADD ファイルとディレクトリをコンテナにコピーします。 ローカルの.tarファイルをアンパックできます。
CMD 実行中のコンテナにコマンドと引数を提供します。 パラメータは上書きできます。 CMDは1つだけです。
WORKDIR あとに続く説明の作業ディレクトリを設定します。
ARG ビルド時にDockerに渡す変数を定義します。
ENTRYPOINT 実行中のコンテナにコマンドと引数を提供します。 引数は存続します。
EXPOSE ポートを公開します。
VOLUME 永続データにアクセスして保存するためのディレクトリマウントポイントを作成します。

Dockerfile公式ドキュメントより抜粋

Dockerfileで使える命令コードは上記の12種類がよく使われ、他にも SHELL や ONBUILD、 HEALTHCHECK、それから廃止予定の MAINTAINER などがあります。

各命令コードについては、実際に Dockerfile を作成・実行する中で確認していきましょう。なお今回は、上記表内の 6つの命令コードを使ってみます(上記表内オレンジ色部分)。

Dockerfileを作る・使う様子の動画

【動画内の Dockerfileコード】 GitHub

Dockerfile① Apacheサーバーのインストール

画像クリックで拡大

上図のDockerfileコード

FROM ubuntu:18.10

LABEL maintainer="oshimamasara@gmail.com"
LABEL version="1.0"
LABEL description="Dockerfileのテスト、Apacheサーバー"

RUN apt-get update
RUN apt-get install -y apache2

CMD ["apachectl", "-D", "FOREGROUND"]


【Dockerfile 実行コマンド】

docker build .
1行目のFROMについて

まず 1行目の命令コード FROM は、ベースとなる Dockerイメージを指定。今回は Ubuntu のバージョン18.10を指定していますが、他には Debian や CentOS、 Alpine などがよく使われると思います。 こうしたベースのイメージは、 Docker Hub の検索機能で 「Base Images」 にチェックを入れればOK(下図参照)。

画像クリックで拡大

また FROM には OS以外の PHP や Python、 WordPress といった Docker Hubで公開されているイメージも指定することができます。

今回使用する Ubuntu:18.10 の機能については、 Ubuntu:18.10 の Dockerfile もしくは docker image history ubuntu:18.10 で確認してみると、大体の内容を掴めるでしょう。

画像クリックで拡大

Dockerイメージ Ubuntu:18.10 の Dockerfile

Docker Hub で公開されているメジャーなイメージの Dockerfile の内容は、だいたい公開されています。これから Dockerfile を作成する上でも参考になるコードでしょう。

画像クリックで拡大

docker image history ubuntu:18.10 の結果

Dockerのイメージの構成内容(レイヤー)を dokcer image history でチェックすることが可能。 Dockerのイメージが、Dockerfile のどういった内容で作成されたのか概要をつかむことができますね。

このようにしてみると今回使用するイメージの Ubuntu:18.10 は、 Ubuntuのクラウド系イメージ 「 ubuntu-cosmic-core-cloudimg-amd64-root 」 をベースにした機能最小なイメージ(OS)であることが確認できます。

2〜4行目のLABELについて

画像クリックで拡大

LABEL は、Dockerのイメージにメタデータを追加できる命令コード。 ”メタデータ” といってもピンとこないですよね、要はイメージへのメモ書きです。

イメージの詳細内容を確認する docker image inspect イメージ名 を実行してみると、冒頭出力されるイメージ情報の中の 「ContainerConfig」という欄に Labels が表示。 このようにイメージにメモ書きを残すことができる機能が LABEL になります。

公式ドキュメントによると、 開発者情報やバージョン、概要などを LABEL で書くといい、とされていますね。

また Docker のチュートリアルを見ていますと、よく 「MAINTAINER」 という命令コードが使われていると思います。この MAINTAINER は廃止予定の命令コードになりますので、なるべく使わない方がいいでしょう。チュートリアルの中で MAINTAINER を使っているようであれば、「それはチョット古い内容?」 もしくは 「公式ドキュメントに従っていない?」 とちょっと疑ってみるほうがいいかもしれません。

それで MAINTAINER に代わる作者の書き方は、

LABEL maintainer="oshimamasara@gmail.com"

LABELの書き方 LABEL キー=バリュー に従って書くと、 docker image inspect した時 maintainer として作者の情報が表示されます。いろいろ LABEL を試してみましょう。

5〜6行目のRUNについて

RUN は、Power Shell やターミナルコマンドを実行するときのリターンキーの役割、「コマンドの実行」を意味します。ソフトウェアのインストールやフォルダを作ったり移動したい時など、たくさんの場面で使用する命令コード。

今回は、ベースイメージの Ubuntu に Apache2 をインストールする作業を RUN に託しています。尚、 RUN で実行されるコンピューターの様子は、自分で Docker コンテナを起動し、 apt-get updadeapt-get install -y apache2 で先に実行しておく方が分かりやすいと思います。特に普段コマンドを触られない方であれば、 Dockerfile で RUN する前に、 Power Shell や ターミナルで先に自分でコマンドを実行することを勧めますね。

【Dockerでコンテナを起動し、apt-get update するコマンド例】

docker run -it ubuntu:18.10 bash

apt-get update
apt-get install -y apache2

ここまでの Dockerfile の内容で、ベースイメージ Ubuntu:18.10 に Apache2 はインストールできたわけですが、 Apacheサーバーの起動を確認しようと思うと FireWall の設定をクリアする必要が。通常の Ubuntuサーバー設定では ufw などの機能を使いますが、 Dockerfile の場合、 CMD という命令コードで Apacheサーバー を起動できます。

7行目のCMDについて

CMD は、コンテナ起動時に指定したファイルやフォルダ、コマンドを実行する命令コード。 CMD 自体書き方が 1つでなく 3通りあってチョット分かりにくいです。はじめの内は例文に従って書いていくことをオススメしますね。

今回の場合は、

CMD ["apachectl", "-D", "FOREGROUND"]

apachectl、これは Apache を操作できるコマンドであり、ファイル。 Apacheの公式ドキュメントを見てみると apachectl startapachectl status など Apacheサーバーを操作している例が紹介されています。また apachectl については、 /usr/sbin/apachectl に存在しますが、システムファイルのため解読不能。

Dockerfile で Apache起動を指定する際は、 apachectl を使えばいい、と覚えておくといいでしょうね。また -DFOREGROUND はパラメーターで決まり文句。 コンテナ起動時、フォアグランドでなにか動かしておかないと、コンテナが終了します。そのためこのようなパラメーターを設定。

CMD ["実行ファイル","パラメーター1","パラメーター2"]

という書式がスタンダードで推奨されています。

以上で、ベースイメージ Ubuntu:18.10 に Apache を自動追加する Dockerfile ができました。

出来上がった Dockerfile をみて内容を理解することに比べて、自分で Dockerfile を組み立てるのは大変です、難しいです。今回ご紹介する Apache サーバーレベルであれば比較的簡単ですが、 WordPress や データベースなど機能的なモノになってくると、そのソフト自体のことをよく理解しておく必要があります。そうでないとイメージに「命令」できません。

また今回は apt-get install というキーワードですが、OSが Ubuntuから CentOS に変われば yum install 、Alpine であれば apk add とキーワードが変わります。つまり RUN については、OSの基本知識も必要に。ちょっと大変ですよね。ここを乗り切るポイントとしては、なるべく一緒の OS で Dockerfile を作っていくことをオススメします。コマンドだけでなく、 OSのディレクトリ構造も違ってきますので、よけいに同じ OS の方が、学習しやすいと思いますよ。

Dockerfileの実行

画像クリックで拡大

docker build .

とコマンド入力することで、Dockerfileが Dockerシステムによって読み込まれ、新しいイメージができます(上図参照)。

docker image ls

とすると一番上の行に新しくできたイメージを確認できます(下図参照)。

画像クリックで拡大

今回は作成するイメージに名前を設定していなかったため、名無しのイメージとなっていますが、 Image ID で作成したイメージを使うことができます。

docker run イメージID

これを実行してみるとIPアドレスがコマンド上に表示されます。ブラウザでこの IPアドレスにアクセスすると、 Apacheサーバーのウェルカム画面が確認できますね(下図参照)。

画像クリックで拡大

予定通り Dockerfile が OS: Ubuntu バージョン 18.10 に Apache を追加してくれたことが確認できます。

せっかくなので Dockerfile で新しく作ったイメージの詳細情報も確認しておきましょう。

docker image inspect イメージID

画像クリックで拡大

イメージの詳細データの上の方に LABEL で設定した内容が書かれていることが確認できます。

尚、今回はポート設定の命令コード EXPOSE を省略しました。省略した理由は、基本 Apache には /etc/apache2/sites-available/000-default.conf ファイル内にデフォルトポートを 80 にするという記載があります。そのため特にポートを指定しなくてもいい今回のようなテストケースでは、 EXPOSE は不要と判断。イメージでポートを設定しなくても、コンテナ作成時に -p とオプションを加えることでポート設定できますので、なおのこと EXPOSE なくてもOKと考えました。

以上が Dockerfile の基本的な一連の流れ。この後は Dockerfile で使える便利な命令コードをいくつか試して、紹介したいと思います。

Dockerfile② ファイルのコピー

画像クリックで拡大

上図のDockerfileコード

FROM ubuntu:18.10

LABEL maintainer="oshimamasara@gmail.com"
LABEL version="1.0"
LABEL description="Dockerfileのテスト、ファイルのコピペ"

RUN apt-get update
RUN apt-get install -y apache2

COPY hello.html /var/www/html/

CMD ["apachectl", "-D", "FOREGROUND"]


【Dockerfile実行コマンド】
docker build -t image01:copy-file .

自分のパソコン内のデータをイメージ内に挿入したい場合は、COPY という命令コードが有効です。 COPY の書き方は、

COPY コピーするファイルもしくはフォルダ 貼り付け先のディレクトリ

【今回の場合】
COPY hello.html /var/www/html/

COPY hello.html /var/www/html/ を実行することで、現在の作業ディレクトリにある hello.html を ベースイメージの ubuntu:18.10 内の /var/www/html/ に自動的に貼り付け。そして出来上がった新しいイメージの /var/www/html/ ディレクトリには hello.html が存在。試しにファイルをコピーした新しいイメージ image01:copy-file でコンテナを起動してみると、 コンテナ内のディレクトリ /var/www/html に hello.html が確認できます(下図参照)。

画像クリックで拡大

コンテナ内のファイル有無を確認するコマンド

docker run --rm -it image01:copy-file bash

cd /var/www/html
ls
cat hello.html


【コマンド補足】
run コンテナの作成と起動を同時に行ってくれるコマンド。
--rm コンテナを起動して、コンテナを残さないコマンド。
-it コンテナに入る時に必要なオプション。 -i と -t をくっつけて -it 。
image01:copy-file コンテナの元になるイメージ名。
bash コンテナに入る時に必要なコマンド。


尚、Dockerfile に書く COPY の場所は、今回の場合であれば Apache をインストールする命令コードの後に書く必要があります。 Dockerfile の自動処理は、上の行から順番に処理されていくため、 COPY する時にコピー先のディレクトリがないとエラーになるためです。

あと実際に hello.html がブラウザで出力されるかチェックしてみましょう。

画像クリックで拡大

コンテナを起動するコマンド

docker run image01:copy-file

【コマンド補足】
run コンテナの作成と起動を同時に行ってくれるコマンド。
image01:copy-file コンテナの元になるイメージ名。


コンテナ起動時に表示される IPアドレスにアクセスすると、 Apache のウェルカム画面。そして 172.17.0.2/hello.html など localhost/hello.html にアクセスすると hello.html が読み込まれている事が確認できます(上図参照)。これで無事 Dockerfile によるファイルのコピペが実現できていることが確認できますね。

ただ実行コマンドを終了しようと思って Ctrl + C を押してもコマンドを終了することができません。この問題を解決するにはコンテナ起動時に -it をつければ OK。 つまり

docker run --it image01:copy-file

とすれば Ctrl + C が効くようになります。

Dockerfile③ git clone

画像クリックで拡大

今回 GitHub からクローンするプロジェクト テトリスゲーム(MITライセンス)

上図のDockerfileコード

FROM ubuntu:18.10

LABEL maintainer="oshimamasara@gmail.com"
LABEL version="1.0"
LABEL description="Dockerfileのテスト、git clone"

RUN apt-get update
RUN apt-get install -y apache2
RUN apt-get install -y git

RUN cd /var/www/html && git clone https://github.com/dionyziz/canvas-tetris.git

CMD ["apachectl", "-D", "FOREGROUND"]


【Dockerfile実行コマンド】
docker build -t image01:git-clone .

Dockerのイメージを作成する際に、 GitHubのプロジェクトをイメージ内にインポートしたいという場面もあるでしょう。先ほど紹介した COPY の場合は、一旦ローカル PCに git clone して COPY すれば、新しく作成するイメージ内に GitHub のプロジェクトを挿入できますが、やや手間に。一方、 Dockerfile 内で起動中のOSに直接 git clone してくれれば、手間も省けますし、プロジェクトのバージョンミスもなくせます。

上記で紹介している Dockerfile の内容を確認してみますと、今回はベースイメージに ubuntu:18.10 を使っていますので、一旦ベースイメージに git をインストールしてから、その後に GitHub のプロジェクトをインポートするという流れ。

【Dockerfile で git をインストールするコード】

RUN apt-get install -y git

上記コード内の -y は、 git インストール中に「インストールしてもいいですか?」と聞かれた際に自動的に「yes」を入力するためのオプションコマンドになります。

【Dockerfile で GitHubプロジェクトをクローンするコード】

RUN cd /var/www/html && git clone https://github.com/dionyziz/canvas-tetris.git

そして git をインストールした後に、 現在起動中の OS: Ubuntu:18.10 内のディレクトリを /var/www/html に移動し、 git clone を実行。これでベースイメージ Ubuntu:18.10 の /var/www/html/ 内に新しく git clone されたフォルダが記録。

この時の注意点としては、 cdgit clone を一度に行う必要がある点。

RUN cd /var/www/html
RUN git clone https://github.com/dionyziz/canvas-tetris.git

と RUN を別々に書くと、 git clone はベースイメージのトップディレクトリに git clone します。 RUN を 1行にまとめて書くか、それとも別々に分けて書くかでは実行ディレクトリが違うということを知っておきましょう。

それでは本当に GitHub からプロジェクトがインポートされているかどうか、今回 Dockerfile で作成したイメージを起動して確認してみましょう(下図参照)。

画像クリックで拡大

Dockerfileでgit cloneできたか確認するコマンド

docker run --rm -it image01:git-clone bash

cd /var/www/html
ls
cd canvas-tetris
ls


【コマンド補足】
run コンテナの作成と起動を同時に行ってくれるコマンド。
--rm コンテナを起動して、コンテナを残さないコマンド。
-it コンテナに入る時に必要なオプション。 -i と -t をくっつけて -it 。
image01:git-clone コンテナの元になるイメージ名。
bash コンテナに入る時に必要なコマンド。


ちゃんと Dockerfile で指示したとおり、 /var/www/html 下に canvas-tetris がクローンされていますね。

またちゃんと Apacheサーバーが動いて、 GitHubのプロジェクトが動いているかブラウザの方も確認してみます。

画像クリックで拡大

Dockerfileでgit cloneできたか確認するコマンド

docker run -d -p 8000:80 image01:git-clone


【コマンド補足】
run コンテナの作成と起動を同時に行ってくれるコマンド。
-d コンテナをバックグランドで起動中のままにするオプション。
-p ポート指定時に使用。 8000は自分のパソコン側のポート番号。80はコンテナ側でほぼ固定値。
image01:git-clone コンテナの元になるイメージ名。


ブラウザで localhost:8000 にアクセスすると Apache のウェルカム画面、 localhost:8000/canvas-tetris にアクセスすると GitHubのプロジェク内容である テトリスゲームが起動。上手く Dockerfile でイメージ内に git clone できていることが確認できました。

Dockerfile④Volumeの設定

画像クリックで拡大

上図のDockerfileコード

# Volumeセット

FROM ubuntu:18.10

LABEL maintainer="oshimamasara@gmail.com"
LABEL version="1.0"
LABEL description="Dockerfileのテスト、Volumeの設定"

RUN apt-get update
RUN apt-get install -y apache2

VOLUME ["/var/www/html"]

CMD ["apachectl", "-D", "FOREGROUND"]


【Dockerfile実行コマンド】
docker build -t image01:volume-func .

Dockerのデータ管理機能の一つに Volume があります。

【Docker Volume参考図】

画像クリックで拡大表示

Docker の Volume 機能を要約すると、一つのデータを各コンテナで共有して使う、というもの。 データは一緒で開発環境だけ変えたい時、テストしたいときに便利な機能です。

そんな Docker の Volume 機能を Dockerfile でイメージに設定することが可能。今回のケースでは、ベースイメージの /var/www/html を Volume 管理。 Apache以外の Tomcat や Nginx 等でサーバーを動かしたい時も、 HTMLデータを Volume で管理しているので、転用しやすいでしょう。

そして Dockerfile への Volume命令コードは、

VOLUME ["ベースイメージの管理したいフォルダor管理したいファイル"]

【今回の場合】
VOLUME ["/var/www/html"]

実際に Dockerfile で指示したとおりに Volume でデータ管理できるかどうかは、コンテナを起動してみるとわかります。

画像クリックで拡大

docker run -d -p 8080:80 image01:volume-func
上記コマンドの説明

docker run -d -p 8080:80 image01:volume-func

run コンテナの作成と起動を同時に行ってくれるコマンド。
-d コンテナをバックグランドで起動中のままにするオプション。
-p ポート指定時に使用。 8080は自分のパソコン側のポート番号。80はコンテナ側でほぼ固定値。
image01:volume-func コンテナの元になるイメージ名。


コンテナ起動後 docker volume ls とコマンド入力すると、 新しくボリュームが作成されていることが確認できます。そしてその Volume が、今回作成したコンテナのものかどうかというのは、下記コマンドで確認可能。

画像クリックで拡大

docker container ls

docker container inspect コンテナ名

上記コマンドを実行するとコンテナの詳細情報が表示。その詳細情報の中に Mounts と書かれた項目があり、それがコンテナのボリューム設定情報を表します(下図参照)。

画像クリックで拡大

docker volume ls で確認した Volume NAME と Mounts に書かれている NAME が同じであることが確認できますね。またせっかくなのでボリュームの中身も確認してみました。

画像クリックで拡大

ベースイメージ /var/www/html 以下にある index.html が Volume にセットされていることが確認。

こうして Dockerfile の中で Volume指示することで、データ活用もあわせた Docker操作を行うことができるようになります。

まとめ

Dockerの中枢機能の一つともいえる Dockerfile。 OSのことやソフトウェアのことを知っておかないと、なかなか難しいですよね。

「Docker、便利そうでこれから必要そうだけど、難しい、、、」「ネットで調べてもよく分からないな。。。」そんな時はプログラミングスクール、どうでしょうか?

4か月間短期集中型の CodeCampGATE では、Webアプリケーションの学習にあわせて Docker もレッスン。Web業界やIT業界で就職・転職を考えている方なら、特にマッチするコースと思います。

CodeCampGATE では無料相談を随時行っていますし、 CodeCamp では無料体験レッスンも随時開催中。

「IT業界で働きたいけど、どうすればいいか分からない」「自分でも大丈夫か、不安」そういった方、是非「無料相談」や「無料体験」を利用して、自分の思いを確認してみて下さい。自分の人生、一度きりです。後悔なきよう、がんばりましょう。

関連記事

オシママサラ
この記事を書いた人
オシママサラ
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp