ぶちのブログ

競プロとCTFが趣味なWebエンジニアのアウトプットの場

docker-compose v3以上でextendできなくなって、ファイルを跨いだanchorとaliasが使えない問題への対応

TL;DR

docker-compose v3でdocker-compose.ymlを綺麗に書きたいけれど、あまり綺麗に書けない。
docker-composeは標準入力からも設定ファイルを読み込めることを利用して、ある程度まではシェルスクリプトを書いて、ゴリ押ししてしまえば良さそう。

はじめに

docker-compose v3以上ではextend出来なくなったため、DRYなdocker-composeファイルを書くには工夫が必要です。

ファイル内で使いまわしたい場合には、こちらの記事のようにanchorとaliasを使うことで対応できます。
また、ファイルを跨いだ場合にも、公式ドキュメント内のこちらの記述のように、複数のymlファイルを使うことができます。

しかし、複数のymlファイルにまたがった場合にanchorとaliasを使えないことがあります。
(anchorとaliasはyaml自体の記法なので、YAMLの仕様書を見ても、複数ファイルでまたがって利用するようなことはできなさそうです。)

補助的なコンテナを、実行するかどうかを選択可能にしたい。

version: '3'

services:
  proxy: &proxy
    build:
      context: .
    command: yarn start

  storybook:
    <<: *proxy
    command: yarn storybook # 必要ない場合はstorybookを起動しないようにしたい

これを、複数のファイルに分けて

version: '3'

services:
  proxy: &proxy
    build:
      context: .
    command: yarn start
version: '3'

  storybook:
    <<: *proxy
    command: yarn storybook # 必要ない場合はstorybookを起動しないようにしたい

として、引数から複数ファイルを読み込ませようとすると、proxyというanchorが見つからずエラーになってしまいます。

自分なりの解決策

公式ドキュメントによると、

-f に - (ダッシュ)をファイル名として指定すると、標準入力から設定を読み込みます。

と書いてあります。つまりymlを読み込んで変換して吐き出すスクリプトと、docker-composeコマンドをパイプで繋いでやることができます!

version: '3'

services:
  proxy: &proxy
    build:
      context: .
    command: yarn start

  storybook:
    <<: *proxy
    command: echo 'you can use docker-compose-up-storybook.sh if you want storybook'

このようなdocker-composeファイルと

#!/bin/bash
set -eux

cat docker-compose.yml |
sed -e s/"echo 'you can use docker-compose-up-storybook.sh if you want storybook'/yarn storybook/" |
docker-compose -f - up

このようなシェルスクリプトを用意しました。

storybookのコンテナが必要なときは普通にdocker-compose upを、不要な際はdocker-compose-up-storybook.shから起動する、と使い分けることで目的が達成できました!