マルチOS対応Docker開発環境の作り方【docker-compose編】


この投稿は Magento Advent Calendar 2019 の12日目です。

前回でDocker for MacのVolumeの問題を解決出来たので、今度はそれをマルチOSにどう対応させていくかというお話です。

OSが異なるとdocker-composeの設定が違ってくるし、なんなら開発者ごとにも設定が異なってきますよね。
「今はdebugモードで起動したい」や「こっちの設定ファイルを使って起動させおきたい」なんてこともよくあります。

基本的なdocker-compose.ymlは同じでいいけど、細かな部分を個々に編集しやすくしたい。そんなときにおすすめな方法が…

docker-compose.override.ymlenv_file です!

docker-compose.override.yml

そもそも docker-compose コマンドでは -f オプションを複数使うことによって、複数の設定ファイルを合体させて使うことが可能です。

docker-compose -f docker-compose.1.yml -f docker-compose.2.yml -f docker-compose.3.yml [COMMAND]

Multiple Compose files (公式ドキュメント)

ただ…とても長くなって打つのが大変ではありませんか?(docker-composeだけで14文字もありますし…
私は毎回これ打つのは嫌ですね!

ではdocker-compose.override.ymlとはなんなのか。
実は、docker-compose コマンドはデフォルトで docker-compose.ymldocker-compose.override.yml を読み込むようになっています。

つまり!

  • docker-compose.yml を共通のベース設定ファイルにする
  • docker-compose.override.yml を環境ごとに変更してもらう

こうすることで、実行時は docker-compose [COMMAND] と打つだけで、環境ごとに対応させることが可能になります!

例としてApache2コンテナを立てる docker-compose.yml を作ってみましょう。

docker-compose.yml
version: "3"
services:
  apache:
    image: apache:7.3-apache
    volumes:
      - {PASS_TO_PROJECTROOT}:/var/www/html

LinuxやWindowsユーザーにはたったこれだけで十分ですよね。
これをさらにdocker-syncにも対応させられるようにしたい、そんなときには docker-compose.override.yml.sample を作成して

docker-compose.yml.sample
version: "3"
services:
  apache:
    volumes:
      - src:/var/www/html
volumes:
  src:
    external: true

このように上書きしたい部分だけを書いていきます。

このsampleファイルをgitで管理させて、逆に.gitignoredocker-compose.override.ymlを追加しておきます。
これでdocker-syncが必要な開発者に docker-compose.override.yml にリネームして使ってもらえば、必要な開発者にのみdocker-syncが使えますよね!

前回同様にdocker-sync.ymlも作成したら、 docker-compose run --rm apache bash してコンテナ内でベンチマークを取ってみましょう。

root@fac0c26e95f7:/var/www/html# time dd if=/dev/zero of=$PWD/benchmark bs=1k count=100000
100000+0 records in
100000+0 records out
102400000 bytes (102 MB, 98 MiB) copied, 0.326605 s, 314 MB/s

real    0m0.329s
user    0m0.050s
sys     0m0.270s

はい!結果から明らかにDocker-syncで同期されていますね

env_file

公式のDockerイメージを使っていると、よく環境変数で起動時の設定を変更できる仕組みになっているものがあると思います。
たとえばMySQLイメージだと、 MYSQL_ROOT_PASSWORD でrootユーザーのパスワードや MYSQL_USERMYSQL_PASSWORD でユーザーを作成することが出来ますよね。

これって開発者ごとに値を変えたくありませんか?

そういうときには docker-compose.yml 内で env_file オプションを使ってみましょう。

docker-compose.yml
version: "3"
services:
  mysql:
    images: mysql:5.7
    env_file:
      - mysql.env

The “env_file” configuration option (公式ドキュメント)

そして指定した mysql.env ファイルを作って、中に環境変数を書いていきます。

mysql.env
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=dbuser
MYSQL_PASSWORD=password

これでMySQLコンテナを起動してみましょう!

$ docker-compose up -d mysql
$ docker-compose exec mysql mysql -u dbuser -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.28 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

ちゃんと起動もして、dbuserでログインも出来ましたね!

こちらも mysql.env.sample のようにサンプルファイルを用意しておいて、コピー&リネームして使ってもらえば便利かなと思っています。

まとめ

これで基本的な設定はsampleファイルとしてGitで管理させ、各開発者に細かいところは好きにいじってもらえる柔軟性も持たせることが出来ました。

実際、以前にMagento2のプロジェクトをDockerで開発環境を作ったときは、「設定はいじらないで」と言ってしまったがゆえに

「configの設定変えたいんですけど、どうしたらいいですか?」
「Macだと遅いんだけどVolumeの設定変えても良い?」

のように使いにくかったようでした。
その反省を活かして設定を柔軟に変更できるようにした結果、今回のような結論に至ったというわけです。

Magento Advent Calendarらしからぬ内容でしたが、Magento2のようにプロジェクトのファイル数が多いものはRead/Writeの回数がとても多くなります。
マルチOSに対応したDocker開発環境を作るにはdocker-compose.override.ymlenv_fileはとても便利ですので、Magento開発者に限らずぜひ使ってみてください!

(これで社内にDockerが普及すると良いな