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

この投稿は [Magento Advent Calendar 2019](https://adventar.org/calendars/4213) の12日目です。

[前回](https://qiita.com/bravebright9/items/f575073d8bae427f5076)でDocker for MacのVolumeの問題を解決出来たので、今度はそれをマルチOSにどう対応させていくかというお話です。

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

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

**docker-compose.override.yml** と **env_file** です！

## docker-compose.override.yml

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

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

> [Multiple Compose files](https://docs.docker.com/compose/extends/#multiple-compose-files) （公式ドキュメント）

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

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

つまり！

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

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

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

```yaml: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` を作成して

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

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

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

[前回同様](https://qiita.com/bravebright9/items/f575073d8bae427f5076#docker-sync)にdocker-sync.ymlも作成したら、 `docker-compose run --rm apache bash` してコンテナ内でベンチマークを取ってみましょう。

```plaintext
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で同期されていますね:thumbsup:

## env_file

公式のDockerイメージを使っていると、よく環境変数で起動時の設定を変更できる仕組みになっているものがあると思います。
たとえば[MySQLイメージ](https://hub.docker.com/_/mysql)だと、 `MYSQL_ROOT_PASSWORD` でrootユーザーのパスワードや `MYSQL_USER`、 `MYSQL_PASSWORD` でユーザーを作成することが出来ますよね。

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

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

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

> [The “env_file” configuration option](https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option) （公式ドキュメント）

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

```plaintext:mysql.env
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=dbuser
MYSQL_PASSWORD=password
```

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

```bash
$ 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.yml`や`env_file`はとても便利ですので、Magento開発者に限らずぜひ使ってみてください！

（これで社内にDockerが普及すると良いな:sunglasses:）