前回の続きでDockerfileについて。
Dockerfileでのコマンド実行(RUN命令)
ベースイメージから実際に活用できるDockerイメージを生成するためには、イメージをプルするだけでは使い物にならないので各種インストールや設定を行う必要があります。
そのためにはコンテナに対してコマンドを実行していきます。
Shell形式での実行
前回の記事でも扱いましたが、コマンドの実行は「RUN」命令で実行します。
「RUN」の後ろはShell形式で記述ができます。
# centOSに対するnginxのインストール RUN yum install -y nginx
自動で実行するので、y OR n の選択でyを選択するために「-y」オプションを付ける必要があります。
Exec形式での実行
Shell形式での実行は「/bin/sh」で実行されますが、Exec形式で実行するとシェルを経由せずに直接実行します。
Exec形式というのは私はあまり馴染みがないですが以下のような形式で記述を行います。
# centOSに対するnginxのインストール RUN ["/bin/bash","-c","yum install -y nginx"]
デーモンの実行(CMD命令)
デーモンなので、Linuxの常駐プログラムの実行になります。
末尾に「d」のつくhttpdなどがデーモンの一種ですね。
イメージの生成はRUN命令を用いますが、コンテナ内でコマンドを実行するにはCMD命令を用います。
CMD命令にもいくつかの記述形式が存在します。
CMD命令はDockerfile内で一度しか実行できないようで、複数記述した場合は最後に記述した内容が実行されるようです。
Shell形式での実行
CentOSイメージをビルドし、コンテナ内でnginxをデーモン実行する際に以下のように実行します。
# nginxデーモン実行 CMD nginx -g 'daemon off;'
Exec形式での実行
RUN命令と同様の形式で記述します。
# nginxデーモン実行 CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT命令
ENTRYPOINT命令で実行したコマンドはコンテナが起動した際に実行されます。
CMD命令で実行した場合との違いは、CMD命令はコンテナの起動時(run)に引数で新たなコマンドを指定した場合、コマンドの上書きが行われます。
対してENTRYPOINT命令ではコンテナで確実に実行されるため、起動時のコマンドを時々によって使い分ける必要がある場合にはCMD命令で実行する必要があります。
また、ENTRYPOINT命令で指定したコマンドに対してCMD命令でオプションを指定することも可能なので、コマンドのオプションを可変にする場合は使い分ける必要があります。
Shell形式での実行
# nginxのShell実行 ENTRYPOINT nginx -g 'daemon off;'
Exec形式での実行
# nginxのExec実行 ENTRYPOINT ["nginx", "-g", "daemon off;"]
ONBUILD命令
ONBUILD命令はビルド時に実行するコマンドをイメージ内に設定する命令です。
経験がないといまいち言ってることが分からないかもしれません。
ベースイメージを生成するためのDockerfile1にONBUILD命令を記述すると
Dockerfile2でオリジナルイメージをビルドする際にコマンドを指定できます。
・例
ONBUILD ADD index.html /var/www/html
webサーバの構築検証
命令の検証
上記の内容だけでは命令イメージがしにくいのでwebサーバの構築を通して検証を行います。
・Dockerfileの内容
# ベースイメージの取得 FROM centos # nginxのインストール RUN yum -y install nginx # ビルド後のINDEXファイルの配置 ONBUILD ADD index.html /usr/share/nginx/html # デーモン実行 ENTRYPOINT ["nginx", "-g", "daemon off;"]
・Dockerfileの実行
docker build -t testos:1.0 /home/ec2-user/docker_work
・Dockerコンテナの生成
docker container run -it --name webserver -p 80:80 testos:1.0
・ブラウザで疎通確認
nginxがコンテナを起動した時点で起動していることが確認できます。
※ENTRYPOINT命令
また、ここではindexファイルは置き換わっていないことが確認できます。
※ONBUILD命令
ベースイメージを元にしてオリジナルイメージを生成します。
・Dockerfile2の内容
# ベースイメージの取得 FROM testos:1.0
・Dockerfile2の実行
docker build -t webserver:1.0 -f deployfile .
・Dockerコンテナ2の生成
docker container run -it --name webserver2 -p 8080:80 webserver:1.0
・ブラウザで疎通確認(ポート:8080)
新たに生成したサーバではindexファイルが置き換わっていることが確認できます。
一人で構築している場合には恩恵がほぼない(最初のDockerfileの時点でindexファイルを配置すればいいから)ですが、インフラ構築とアプリ構築がチームで分かれていて、複数人でアプリ開発を行っている場合などには、各自の環境でここでいうDockerfile2を実行することでそれぞれの環境に同一のインフラ環境を構築して、アプリはそれぞれのものをデプロイするなどの運用が可能になります。