最近仕事で docker-compose.yml
をメンテする機会が多く、その際に重宝したDRYに書くテクニック2つです。
Extension fields
compose fileのバージョン3.4
以降から、Extension fieldsという機能が利用できるようになりました。
これは、YAMLのaliasとanchorの機能をdocker-compose.yml
中でも利用できるようにしたものです。
使いどころ
- 同じ環境変数を複数のコンテナに設定しなければならない
- 複数コンテナで同じパスでマウントするvolumeがある
使用例
サンプルとして、大量の同じenvironment
を各コンテナで指定しなければならない例を見てみましょう。
適用前は次に示すように愚直に記述しています。
---
version: '3.7'
services:
nginx:
image: nginx:alpine
ports:
- 80:80
environment:
ENV: development
USER: user
HOST: example.com
HOGE: hoge
FUGA: fuga
FOO: foo
BAR: bar
rails:
image: ruby:alpine
environment:
ENV: development
USER: user
HOST: example.com
HOGE: hoge
FUGA: fuga
FOO: foo
BAR: bar
これをExtension fieldsを使用して書くと次のように書けます。
---
version: '3.7'
x-environment: &environment
ENV: development
USER: user
HOST: example.com
HOGE: hoge
FUGA: fuga
FOO: foo
BAR: bar
services:
nginx:
image: nginx:alpine
ports:
- 80:80
environment: *environment
rails:
image: ruby:alpine
environment: *environment
x-environment
に&environment
でaliasを設定し、*environment
で展開して利用しています。
このように書くことで、環境変数を変更する際、すべてのコンテナの記述を変更してまわらなくてもよくなります。
注意点
-
version
には3.4
以降を指定する必要があります - トップレベルに記載する場合はキーを
x-
で始める必要があります
YAMLのalias、anchorは他にも記述方法がいくつかあります。
以下のサイトが参考になるかと思います。
https://tech-1natsu.hatenablog.com/entry/2018/12/16/004215
Multiple Compose files
Multiple Compose files(公式ドキュメント)
Multiple Compose filesはその名前の通り、複数のcomposeファイルを使う方法です。
通常、docker-compose
コマンドを利用すると、カレントディレクトリ(存在しない場合は上位のディレクトリ)のdocker-compose.yml
が利用されます。
このファイルは、-f
オプションかCOMPOSE_FILE
環境変数で指定を変更することができます。
docker-compose.develop.yml
を使って、docker-compose up -d
を行う場合は次のようになります。
# -fオプションの場合
docker-compose -f docker-compose.develop.yml up -d
# 環境変数の場青
COMPOSE_FILE=docker-compose.develop.yml docker-compose up -d
# or
export COMPOSE_FILE=docker-compose.develop.yml
docker-compose up -d
この-f
オプションか環境変数COMPOSE_FILE
に複数のdocker-compose用YAMLファイルを指定することで、マージされた内容が利用できます。これがMultiple Compose filesです。
使いどころ
- 開発時は追加で起動するコンテナがある
- 連携サービス用コンテナの有無や、環境変数などを自由に切り替えられるようにしたい
使用例
以下のような例を想定します。
- nginxとrailsの2つのコンテナの環境
- 開発時はnginx側で8080とホストの8080をバインドしたい
- railsには開発時のみ、
HOGE=hoge
という環境変数を設定したい
普通にやろうとすると、docker-compose.ymlを2種作り、それぞれに似た内容を記述してしまい、DRYになりません。
Multiple Compose filesの機能を使いDRYに書くと、下記のように記述できます。
---
version: '3.7'
services:
nginx:
image: nginx:alpine
ports:
- 80:80
rails:
image: ruby:alpine
---
version: '3.7'
services:
nginx:
ports:
- 8080:8080
rails:
environment:
HOGE: hoge
development.yml
には、開発時のみに利用する設定を記述しています。
利用時は以下のように使います。
# 非開発時
docker-compose up -d
# 開発時
COMPOSE_FILE=docker-compose.yml:development.yml docker-compose up -d
このように設定することで、開発時にはdevelopment.yml
の内容とマージされた設定でコンテナが起動できます。
docker-compose config
コマンドで最終的なYAMLを表示できるので、development.yml
を追加した場合の設定を見てみましょう。
COMPOSE_FILE=docker-compose.yml:development.yml dc config
# 以下が出力される
services:
nginx:
image: nginx:alpine
ports:
- published: 80
target: 80
- published: 8080
target: 8080
rails:
environment:
HOGE: hoge
image: ruby:alpine
version: '3.7'
想定どおりになっていますね。
注意点
マージの挙動に関しては、下記のようになります。(詳細は公式ドキュメントを参照してください)
- キーが無い場合:追加
- キーがある場合:後で指定したファイルの内容で上書き
- リストの場合:リストの要素を追加
docker-compose
コマンドを利用するたびに設定するのは面倒なので、direnv等を使い、自動でCOMPOSE_FILE
環境変数が設定されるようにすることをおすすめします。