Dockerfileを使用したDockerイメージの作成

Docker公式ロゴ1b
©2023 Docker Inc. All rights reserved

 前回、Ubuntuの公式Dockerイメージに手動にてApache及びPHPをインストールし、最後に「docker commit」コマンドで新たなDockerイメージを作成する方法について書きました。

 この方法でもDockerイメージは作れますが、システム運用の観点から考えた場合は推奨されません。

 Dockerコンテナ作成を手動で構築するのは、初期段階の試行錯誤をするフェーズでは有効だと思います。

 しかし、作業手順の正確性、手動によるオペレーションミス、問題が発生した際のデバッグ面、情報共有の利便性など、システム運用の面では不利な点が多いです。

 本記事では、dockerfileを使用したDockerイメージの作り方について解説します。

 作成するDockerイメージは、別記事「dockerfileを使わずにDockerイメージを作成する」で作成しましたDockerイメージと同じサービス内容になるようにします。

本記事は、Apache+PHPを使用した実用できる環境の構築が目的ではなくて、Dockerイメージの作成方法の解説を行うためのものです。

ApacheやPHPは、DockerHub上に公式イメージが公開されておりますが、同じ理由により使用しません。

利用するUbuntuやApache、PHPなどは、最新版ではなくてデフォルトでインストール可能なものになります。

本記事を参考にして構築した環境は、セキュリティ的に問題があることもありますので、本番環境などでご利用にならないでください。

検証目的でのご利用をお願いいたします。

dockerfileを作成する

 dockerfileには、まず最初にDockerコンテナのベースとなるDockerイメージを指定します。

※ベースとなるDockerイメージは、通常は基本的なツール群のみがインストールされた素の状態に近いOSが使われます

 そこに、Dockerイメージを作成する際に実行するコマンドを順に記述していきます。

 Dockerコンテナの外に開放するポートやDockerコンテナ起動時に自動実行されるスクリプトなどを登録することも可能です。

 ですので、ベースとなるOSにソフトウエアを構築するためのインストール手順を事前に確立させていたほうが、dockerfileの作成がスムーズにすすみます。

 以降では、別記事「dockerfileを使わずにDockerイメージを作成する」で行った手順を基にdockerfileを作成していきます。

 別記事で行った手順は以下の通りです。

  • ベースイメージの取得
# docker pull ubuntu:20.04
  • CentOSコンテナにApacheをインストール
# apt update
# apt install apache2
※途中でTime Zone設定を行う場合があります
  • CentOSコンテナにPHPをインストール
# apt install php
  • PHPアプリケーションのインストール
# docker cp myapp.php <Apache+PHPコンテナのコンテナID>:/var/www/html/
  • Dockerコンテナの起動
# docker run -d -p 8080:80 my-httpd-php apachectl -D FOREGROUND

 これをdockerfileの形式で記述すると、以下の通りになります。

FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Tokyo

RUN apt update && apt install -y apache2

RUN apt install -y php

COPY myapp.php /var/www/html/

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

※Dockerコンテナ起動時のポート指定は、後述してますが、起動時に指定します。dockerfile内で指定することも可能です。

 Dockerホスト内の任意の空のディレクトリを作成し、上の内容のdockerfileを作成します。

 ファイル名は「dockerfile」です。

 また、別記事「dockerfileを使わずにDockerイメージを作成する」内で作成したmyapp.phpも同じディレクトリに入れておきます。

 念のため、別記事で作成したmyapp.phpの内容を再掲します。

<html>
 <head>
 <title>
 myapp.php
 </title>
 </head>
 <body>
 <b>
 <?php
 echo "This machine is ",gethostname(),".";
 echo "<br>";
 echo "This machine's IP-address is ",$_SERVER["SERVER_ADDR"],".";
 echo "<br>";
 echo "<br>";
 echo "Your machine's IP-address is ",$_SERVER["REMOTE_ADDR"],".";
 ?>
 </b>
 </body>
 </html>

作成したdockerfileを使用してDockerイメージを作成する

 作成しましたdockerfileとmyapp.phpを置いたディレクトリをカレントディレクトリとして、Dockerイメージを作成するコマンドを実行します。

 コマンドのフォーマットは以下のとおりです。

$ docker build --rm -t <dockerイメージ名> .

 前回のDockerイメージ名はmy-httpd-phpでしたので、今回はmy-httpd-php-2にします。

 以下のコマンドを実行してください。

$ docker build --rm -t my-httpd-php-2 .

 しばらくするとプロンプトが戻ってきます。

 最後に「Successfully built xxxxxxxxxxxxx」のメッセージが出力されていれば正常です。

※xxxxxxxxxxxxxは任意の文字列です

 「docker images」コマンドでDockerイメージmy-httpd-php-2が作成されていることを確認しましょう。

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-httpd-php-2 latest 8b0756a1ea75 7 seconds ago 281.4 MB
my-httpd-php latest a2f69b374be4 6 hours ago 343.1 MB

Dockerコンテナの起動

 では、作成したDockerイメージを使用してDockerコンテナを起動します。

 以下のコマンドを実行してください。

$ docker run -d -p 8080:80 my-httpd-php-2

 Dockerコンテナが起動されましたら、Dockerホスト外のPCからブラウザで以下のURLにアクセスしてください。

http://<DockerホストのIPアドレス>:8080/myapp.php

 「Apache+PHPコンテナ」のホスト名とIPアドレスおよび接続元のIPアドレスとが表示されたと思います。

dockerfileの構文について

 では、dockerfileとDockerイメージ作成コマンドについて詳しく見てみましょう。

 先ほどのdockerfileを再掲します。

FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Tokyo

RUN apt update && apt install -y apache2

RUN apt install -y php

COPY myapp.php /var/www/html/

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

 最初の「FROM」は、ベースイメージを指定する命令です。「ubuntu:20.04」が指定されています。

 次の「ENV」は、Apache2のインストール時に、tzdataセットアップの部分で処理が中断してしまうのを回避するために設定します。

※以下のブログ記事を参考にさせていただきました。ありがとうございます。

[Docker] build tzdata タイムゾーン選択回避方法(ubuntu)
なぜか突然Dockerfileをbuildする時にtzdataでタイムゾーンの選択を求められるようになりました…

 次の「RUN」は、ベースイメージ内で実行するコマンドを指定する命令です。前回手動で実行したコマンドが記載されてます。

 1つ目の「RUN」がApacheのインストールで、2つ目の「RUN」がPHPのインストールになります。

 次の「COPY」は、Dockerホスト上にあるファイルを、作成するDockerイメージ内の所定のディレクトリにコピーします。

 最後の「CMD」は、Dockerコンテナ起動時にDockerコンテナ内で実行するコマンドを指定する命令です。

 Apacheのバイナリファイルを起動するように指定しています。起動時のオプションも指定しました。

 このように、最初にベースイメージを指定して、あとはそのDockerイメージを更新する処理やその他のオプションなどを順番に指定していくことでdockerfileを作成していきます。

 今回使用した命令はほんの一部です。

 dockerfileに関する詳しい説明は以下を参照してください。

Docker公式サイト

Dockerイメージ作成コマンドのオプション

 dockerfileを使用してDockerイメージを作成する際に以下のコマンドを実行しました。

$ docker build --rm -t my-httpd-php-2 .

 本節では、このコマンドについて説明します。

 「--rm」は、Dockerイメージの作成処理の過程で生成されるテンポラリファイルを、Dockerイメージ作成処理後、自動的に削除するオプションです。

 「-t」は、作成するDockerイメージ名を指定します。

 最後に、「.」が付いていますが、ここには読み込むdockerfileが存在するディレクトリを指定します。

 上記の場合、「.」はカレントディレクトリですので、カレントディレクトリに存在するdockerfileを読み込むための指定になります。

 dockerfileのファイル名は、他の名前を指定することも可能です。

Dockerコンテナの起動コマンドのオプション

 最後は、作成したDockerイメージを用いたDockerコンテナの起動です。

$ docker run -d -p 8080:80 my-httpd-php-2

 「-d」は、デーモンモードで起動するオプションです。

 「-p」は、起動したDockerコンテナの公開ネットワークポートの指定と、Dockerホストのネットワークポートの接続を指定することができます。

 フォーマットは、以下のとおりです。

-p <Dockerホストポート>:<Dockerコンテナの公開ポート>

おわりに

 本記事では、dockerfileを使用せずにDockerイメージを作成した手順を参考にしてdockerfileを作成してみました。

 dockerfileがどのようなものかご理解いただけましたでしょうか。

 このようにdockerfileを作成してDockerイメージを作成することで、以下のような利点があります。

  • Dockerイメージが可視化される
  • イメージ作成やイメージメンテナンス時の労力・ミスの低減
  • Dockerイメージ配布の利便性

 などなど

 また、「docker pull」コマンドでDockerイメージを取得することと、そのDockerイメージを作成した際に使用したdockerfileを入手し「docker build」コマンドでDockerイメージを作成することは同じである、とも言えます。

 例えば、誰かにDockerイメージを送る場合、dockerfileをメールに添付するという方法もある、ということです。

 バイナリファイル群であるDockerイメージとテキストファイルであるdockerfile。

 メリット・デメリットを見極めて使いこなしていただければと思います。

 最後までお読みいただきありがとうございました。

コメント