Dockerfile からの build 例
前回に、 CentOSの6 に banner と figlet コマンドを入れたイメージを作成しました。軽めのアレンジでしたね。同じイメージを Dockerfile を build することで用意してみます。そ、そんなに軽い女じゃないのよ!
Dockerfile 内のコマンドはそれほど多くないので、実例を見たほうがわかりやすいです。深く考えず、会ってみたほうがわかり合えるものです。
$ echo ANGERME > test.txt
$ cat > Dockerfile
FROM centos:6
RUN yum install -y epel-release && yum install -y banner figlet
COPY test.txt /tmp/test.txt
CMD banner LOVE ; cat /tmp/test.txt | figlet
^D
$ docker build -t test .
$ docker run test
はい、できましたね。さくっと終わっちゃいました。まだ会ったばかりなのに。
四種のコマンドを使いました。ざっくりとは、以下です。
- FROM … ベースのイメージを記載 (必須)
- RUN … パッケージ追加など、直ちに シェル(sh) 上で実行するコマンド
- COPY … ホストOS側からコピーして送り込むファイルを from to で記載
- CMD … コンテナ起動時に実行するコマンド (CMD文は、最後の一つだけが有効)
細かくは 日本語リファレンス をご覧ください。他のコンテナとの連携のため、 EXPOSE コマンドでポート連携を、VOLUME コマンドでマウントを出来ます。
docker-compose コマンド
たとえばLAMP(Linux, Apache, MySQL, PHP)の動作環境を作るとします。それらのイメージからそれぞれのコンテナを用意して、互いに連携して一個ずつを立ち上げることを思いつきますが、それはもちろん可能です。
なのですが、一個づつ pull, run, exec, 設定, restart, そして commit して、えーっと、、なんか心が折れてしまいそうですよね。もう想像するだけで面倒な気分です。工程が長すぎてずるずると、倦怠期になりそうです。
このようなとき、 docker-compose コマンドを使います。複数のコンテナの情報や設定を束ねておき、全部まとめて起動・シャットダウンできます。こちらも、実例を見たほうが早そうです。複数人が集い、今夜は特別なパーティです。
docker-compose.yml ファイル
ここまでに導入済みの MySQL 5.7 のイメージと、今回に新規に用いる Apache + PHP 7.2 のイメージとを、連携させてみます。
そのままの名前ですが、 ファイル docker-compose.yml に記載します。そうです、YAML形式です。XMLのように使えますが、マークアップ言語の煩わしさはなく、行単位でさくさくと編集しやすい書き方です。閉じたり開いたりされると、なんだか僕、落ち着かないのです。
Ruby好きな信者はなぜか、「Rubyで使われるYAML」みたいな枕詞を付けたがるようですが、なんか意味不明です。Rubyと直接に関係ない一般的な書式であり、XMLやJSON形式のように色々な所で使われています。例えば、Javaで使われるXML、な言い方はしないような。うーむ。
version: "2"
services:
app:
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./:/var/www/html
ports:
- 80:80
links:
- mysql
depends_on:
- mysql
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=pass
- MYSQL_DATABASE=php
ports:
- 9999:3306
「app」範囲にて、 手元の Dockerfile を指定しています。その中の「volume」 にて、ホスト側のカレントディレクトリを、 /var/www/html つまりは Apache の ドキュメントルートにマウントしています。「links」 と「depends_on」 にて、 mysql の範囲との連携を指示しています。
「mysql」範囲にて、 導入済みの mysql:5.7 イメージを指定しています。あとはわかりますね。
Dockerfile の内容は以下です。
FROM php:7.2-apache
RUN docker-php-ext-install pdo_mysql
FROMにて便利なベースのイメージ(PHP7.2とApacheの合体版)を指定して、RUN にて MySQL(DB) との連携に必要なパッケージを導入しています。シンプルですね。単純な愛こそ尊いものです。
実行
これら二つのファイルを用意したら、以下で実行します。シンプル。
$ docker-compose up -d
「-d」は docker run コマンドと同様で、バックグラウンドで実行する指示です。
完了したら、以下だけの内容の、 index.php ファイルを手元に用意して、
<?php
phpinfo();
ブラウザから http://localhost/ にアクセスします。PHPの動作を確認できるかと思います。では、MySQL につないでみます。
$ docker-compose exec mysql mysql -u root -p php
pass [enter]
# exit
SequalPro などの MySQL クライアントから、 127.0.0.1:9999 root/pass にて接続できることを確認してみてください。
シャットダウンするときは、以下です。シンプル。ぷるぷると終了。
$ docker-compose down
操作の対象を特に指定していないのは、無指定のときは手元にある yml ファイルをもとに動作するからです。もちろん指定もできますが、ここでは操作をなるべく単純にしています。
ここで以下を行うとわかりますが、
$ docker ps
ご想像の通り、二つのコンテナが動作しています。もちろん、docker-compose コマンドではなく、個々のコンテナに対して docker exec や docker restart などを実行できます。
ちなみに
my.cnf 的な MySQL の設定ファイルをいじくって調整することがあるかと思います (例: /etc/mysql/conf.d/docker.cnf ) 。このとき、設定変更を反映させるためには、MySQL の再起動が必要ですよね。
そんなとき、コンテナIDをdockerコマンドのパラメータに与えるのですが、長いコンテナIDの全てを書く必要はありません。特定できれば充分です。そもそもコンテナの指定は、複数が可能なのです。
具体的には、docker ps コマンドの実行結果から、対象のコンテナIDがわかりますが、このうち頭の数文字(3〜4文字ほど)だけを与えれば良いです。
この頭文字を用いて、「docker exec -it コンテナIDの一部 bash」にて shell に入って設定を変更。そして「docker restart コンテナIDの一部」にて再起動。というような操作が楽ちんっぽいです。
あ、何か変更したらば commit を忘れずに。永続的に DockerHub へ保存するときは、そう、 push ですね。楽しかった思い出は、なるべく忘れないようにしたいものです。push push!
最後に
さくさくな「実践入門」の章としては、今回が最後の記事となります。この支配からの卒業。夜の校舎、窓ガラス、壊してまわった。いえ、何かが出そうで怖いので、夜に行ったことはありません。ビビりです。
壊したくなったのは物ではなくて、「Docker 入門」とかでGoogle検索したときに出てくる情報がまあ、ほとんど役に立たない、という状況です。大きな会社の技術者がセミナー向けに書いたものだけ見るのが良いです。Qiitaは×。
操作やソースの一部だけ切り取られても全く意図が分からないですし、日本人とは思えない文章ばかりで。間違いや勘違いも多く、Dockerは新しめのツールなので書いているかたが若めなのか、なんだかしょんぼりしました。
これはDockerに限ったことではありませんが、コマンドや仕組みなどの正しい理解をするには、本家のリファレンスやマニュアルを見るのが、結局は一番早くて確実です。
じゃあ、なぜお前はこの連載を書いたのだっ、と思われそうですね。それはまず、公式の日本語訳がいまいちだったから、です。また、スタートアップにしては内容が高度であり、はっきり言って難しすぎ。そっと閉じる感じです。
最初にやりたいことは大体、LAMP+αの環境を使いたいとかで、NginxやWordPressを動かして実験をしたり、MySQL+PHPの開発環境を手元に置いて色々と試したい、という所でしょう。そのような具体的な目的を短時間で達成できるよう、さくさく出来るように、情報をまとめようと思ったのです。
では今夜は、これまでで一番の派手なパーティをするぞ! PARTY HARD!! とっても楽しかったです。少しでも役に立っていたら嬉しいです、気持ちよくなっちゃいます。結局はLOVEでしょ。またお会いしましょう。