こんにちは。ヤスタカです。ビアガーデンの季節ですね!
先日、夜明け告げるルーの歌という映画を見に行って来たんですが、これはアニメが好きな全人類に観て欲しいと思う素晴らしい作品でした!監督が四畳半神話大系や先日まで公開されていた夜は短し歩けよ乙女の湯浅政明監督なので他の作品が好きな方はぜひ見に行ってみてください。
さて、この Docker 連載も 4 回目となり、いよいよ Dockerfile を使っての構築に入っていけそうです。 絶対に挫折しない!オープンソースソフトウェア「Docker」入門編 絶対に挫折しない!オープンソースソフトウェア「Docker」入門編 #02 絶対に挫折しない!オープンソースソフトウェア「Docker」入門編 #03
Dockerfileってなに?
前回までの Docker コマンドで、Docker イメージから環境を構築する手順や起動方法などを見てきましたが、結局コマンドをその都度打って構築していたのでは、あまり Docker のよさは体感できなかったと思います。
そして、ようやく 4 回目にして その環境構築作業をコードとして残しておける&共有できるという Infrastructure as Code の世界に入っていけるカギとなるのが、この Dockerfile です。
Dockerfile という設定ファイルに環境構築手順を記載しておき、そこからイメージを生成することによって、いつでも同じ構成の環境が迅速に作成できるという利点があります。
Dockerfileの命令群
まずファイル名は必ず「 Dockerfile 」という名前にしてください。
Dockerfile は命令行、コメント行、空行から構成されていて非常にシンプルな構造です。Dockerfile に記述できる内容は以下のとおり。
命令 | 説明 |
---|---|
FROM(必須) | ベースとなるイメージの指定 |
ADD/COPY | イメージ内にファイルやディレクトリを作成・コピーする |
ARG | 値をbuildサブコマンド実行時に指定できる変数を設定 |
CMD/ENTRYPOINT | コンテナ起動時に最初に実行するコマンドを指定 |
ENV | イメージ作成やコンテナ実行の際に環境変数を設定 |
EXPOSE | コンテナが待ち受ける通信ポート番号を指定 |
LABEL | イメージに付加する管理情報 |
MAINTAINER | イメージ作成者の名前 |
ONBUILD | ビルド完了後に実行される命令 |
RUN | コンテナ内でコマンド実行 |
STOPSIGNAL | コンテナ停止に使う信号(シグナル)の種類指定 |
USER | イメージ作成時やコンテナ実行時のユーザー指定 |
VOLUME | ボリュームのマウント |
WORKDIR | 作業ディレクトリの指定 |
これですべてとなります。「え? これだけ?」と思うくらい少ないですよね。そうなんです、全部で 14 個です。
でも、この命令を組み合わせることで、いろんな構成の環境を構築できちゃいます。
Dockerfile に最低必要な記述はベースイメージの指定をする FROM 命令です。
Dockerfileの書き方
例えば Web サーバーを立ち上げて php をインストール、index.php を表示させたい場合の Dockerfile はこんな風になります。LAMP環境ってやつですね。
FROM centos:6 #centos用のベースイメージを指定。:以降のタグでversionを指定。
MAINTAINER yasutaka <xxxx@gmail.com> #メンテナーの記述。無くてもよいです。
RUN yum -y update #とりあえずこれするよね
RUN yum -y install httpd php mysql-server #apache, php, mysqlのインストール
ADD index.php /var/www/html #ローカルのindex.phpをコンテナ内の指定ディレクトリにコピー
EXPOSE 80 #port80番を開放
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] #バックグラウンドでの起動だとコンテナが停止してしまうため、この指定をする。
またDockerfileと同じ場所にこのようなindex.phpファイルをひとつ用意しておいてください。
<?php
phpinfo();
Dockerfile の説明はコメントで記載しているので、一行ごとに何をやっているかを確認しながら読んでみてください。
Dockerfileからのイメージ生成
さて、先ほど作成した Dockerfile からイメージを作成するには
docker build -t apache-web . #apache-webという名前を付けてイメージを作成
コマンドは Dockerfile がある位置まで移動して実行してください。
これでdockerのイメージがまず作成されます。次はこのイメージからDockerコンテナを起動します。
docker run -d -p 80:80 --name web apache-web #apache-webイメージからwebという名前のdockerコンテナを起動 -p オプションでポートフォワード
そうすると、Dockerfile に記載されたとおりの構成でLAMP環境のコンテナが作成されます。
localhost にアクセスすると、このようなphpinfoの画面が表示されたでしょうか?
これでwebサーバーとphpは正常に動いてることが確認できました。
Dockerfile作成時の注意点
さきほど作った Dockerfile では、ひとつの Dockerfile で apache, php, mysql のインストールまで行ってましたが、本来 DockerはこのようにひとつのコンテナをVPS環境のようにいろんなものをインストールして構築するのはよろしくないです。
Dockerfile は 単機能かつ短命なものであるべき という考え方で作成すべきです。できるだけ単一のプロセスだけを稼働させるのがベストです。
その理由はDockerfileのメンテナス性の向上です。例えばosを変更したり、webサーバーとしてnginxを使いたい、phpのバーションを変えたいという時に全てひとつのDockerfileで作ってしまうと、その度ごとに変更が生じてしまいます。それは他のモジュールとの依存関係も含めて結構な修正になっていまうこともしばしば。
なので、なるべくひとつのコンテナの機能を小さくして、そのコンテナ同士をレゴブロックのようにうまく組み合わせながら目的とするものを作っていくイメージを持つとよいでしょう。
まとめ
今回は Docker のキモとも言える Dockerfile の書き方を見ていきました。これさえあればもう環境構築をそれぞれの local上 で行わなくてもよくなるので、開発環境を整えるのにはとてもよいと思います。ただ、今回の Dockerfile では新たな問題が発生してしまいました。
「 1 コンテナ 1 プロセスを目指す」と書いて起きながら、今回は Web サーバーと php と mysql がインストールされているモリモリの Dockerfile になってます( mysql については使われてさえいませんが……)。
そこで、次回はこれを分割し、メンテナンスしやすい Dockerfile を作成するコツ、Docker Compose という機能を使ってそこらへんを解決していこうと思います。
それでは!
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。