🐳

docker-compose.ymlは起動時に複数指定すると差分を上書き適用できる

2022/04/21に公開

結論

起動時にdocker-composeファイルを複数指定すると差分を上書きして適用してくれる仕組みを利用すると、環境別に複数ファイルをダブルメンテしなくていい。
https://docs.docker.jp/compose/extends.html

docker-syncを使う環境と使わない環境2つ用意する場合は、docker-compose.ymlにはdocker-syncなしの設定を定義し、docker-compose.with-docker-sync.ymlのような別ファイルにdocker-sync用の差分だけを定義することでダブルメンテを避けつつ異なる環境を用意できる。

docker-sync-with-docker-sync.yml
version: "3"
services:
  web:
    volumes:
      - web-native-osx-sync:/app:nocopy
volumes:
  web-native-osx-sync:
    external: true

docker-syncを使わない環境

$ docker-compose up

docker-syncを使う環境

$ docker-sync start
$ docker-compose -f docker-compose.yml -f docker-compose.with-docker-sync.yml up

困っていたこと

普段MacでDocker Desktopを使って開発してるんですが、そのままだとファイルの同期にかなり時間がかかるのでdocker-syncを使っています。
ただチームにはWindowsを使って開発しているメンバーもいて、そのメンバーは同期の遅さに苦しんでいない、かつ安定性を重視してdocker-syncを使っていません。

これまではほぼ同じ構成のファイルを2つ用意して、docker-sync用にvolumesのところだけ書き換えて使っていました。
docker-compose.ymlに変更を加えるときにはdocker-compose.with-docker-sync.ymlにも同じ変更を適用して…とめちゃめちゃダブルメンテでたまに変更漏れが起こったりしていました。

docker-sync使わないメンバー

$ docker-compose up

docker-compose.ymlを参照して起動

docker-sync使うメンバー

$ docker-sync start
$ docker-compose -f docker-compose.with-docker-sync.yml up

docker-sync.ymlの設定にしたがってdocker-compose.with-docker-sync.ymlを使って起動

解決策

ダブルメンテどうにかしたいな〜と思ってDocker Composeのドキュメントを眺めていたら、どうやら複数ファイルを起動時に指定することで差分を上書き適用してくれるということを知りました。

サービスの定義が両方のファイルに存在した場合、Compose は 設定の追加と上書き に示すルールに従って定義設定をマージします。

https://docs.docker.jp/compose/extends.html#id14

ということでdocker-compose.ymlと定義が被っているところはざっくり削除して、docker-syncを使うにあたって上書きしたいところだけ定義します。

docker-sync-with-docker-sync.yml
version: "3"
services:
  web:
    volumes:
      - web-native-osx-sync:/app:nocopy
volumes:
  web-native-osx-sync:
    external: true

そして以下のように両方のファイルを読み込ませることで設定を上書き適用できます。
これでダブルメンテから開放されました。

$ docker-sync start
$ docker-compose -f docker-compose.yml -f docker-compose.with-docker-sync.yml up

補足

因みにdocker-syncを使うときはdocker-sync.ymlのオプションに以下のように使用するファイル名を渡しておくとdocker-sync-stack startだけで起動できて便利です。

docker-sync.yml
version: "2"

options:
  compose-file-path: ['docker-compose.yml', 'docker-compose.with-docker-sync.yml']  
syncs:
  web-native-osx-sync:
    src: './app'
$ docker-sync-stack start

This will first start the sync service like docker-sync start and then start your compose stack like docker-compose up.
You do not need to run docker-sync start beforehand!
This is very convenient so you only need one shell, one command to start working and CTRL-C to stop.

https://docker-sync.readthedocs.io/en/latest/getting-started/commands.html#start-1

Discussion