31
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

V3以降はdocker-compose.ymlで外部ファイルを参照出来ない!

Last updated at Posted at 2018-11-26

YAML include等と検索した所、
RubyやPython等の独自仕様が山ほど出てきて死んだので備忘録として書き残す。

結論

  • V2まで: extendsを利用する
  • V3以降: docker-compose.override.ymldocker-compose.ymlと同じディレクトリに配置するとマージしてくれる

どちらも後述で紹介しているので、
やり方だけ知りたい方はそちらを参照。

前提: そもそもYAMLで外部ファイルを参照する仕様はない

YAMLはデータをシリアライズ(文字列化)した文書ファイルでしかない。
外部ファイルを参照したければ、自前のプログラミング言語等で勝手に実装する必要がある。

例えばPHPのSymfonyというフレームワークでは、
YAMLファイルの上部にimportsというおまじないを記載することで外部ファイルを読み込んでYAMLファイル同士をマージして扱う事が可能となる。
参考記事: How to Import Configuration Files/Resources - Symfony Docs

これはYAMLファイルとしてはimportsという文字列の配列を定義しただけ。
これを読み取ったSymfonyが勝手に別のYAMLファイルも読み込みマージ、
巨大な連想配列を生成し直して、そこから自身のフレームワークの挙動を制御しているだけの話だ。

なので他の言語やライブラリでSymfonyと同じやり方を試してもうまくいかないだろう。
もしそのツールやライブラリの開発者が必要と判断したのなら、
独自の外部ファイル参照の仕組みが実装されることになる。
(その開発者が前例のSymfonyを元に同じような仕組みを採用するケースはあるかもしれないが期待薄)

例えばDockerのdocker-compose.ymlで外部ファイル参照がしたければ、
YAML 外部ファイルといったワードで検索しても時間の無駄。
docker-compose.yml 外部ファイルという風にツールやフレームワーク等を意識したワードとセットにして検索してみよう。

docker-compose.ymlで外部ファイルを参照する方法(V2まで)

※以下の方法はV2までのファイルフォーマットであり、
V3からは「フラットな構築にしなさい」というありがたいお言葉と共に取り除かれてしまった。

公式サイト: サービスの拡張 - Docker Compose

Docker Compose の extends (拡張)キーワードは、異なったファイル間で設定を共有できるだけでなく、異なったプロジェクトでも利用可能です。拡張サービスは複数のサービスを持っている場合、一般的な設定オプションの再利用に便利です。 extends を使えば、1箇所だけでなく、どこでも利用可能なサービス・オプションの共通セットを定義できます。

docker-compose.yml

extendsキーで外部ファイルを指定し、サービス名をキーにまるごとテンプレートとしてまるごと持ってくる。
その後、コンテナの用途に合わせてプロパティを上書き指定していく形になる。

web:
  extends:
    file: common-services.yml
    service: webapp
  ports:
    - "4000:8080"

common-services.yml

webapp:
  build: .
  ports:
    - "8000:8000"
  volumes:
    - "/data"

本題: V3でextendsが取り除かれた話

アップグレードガイドを確認した所、こんな風に書いてある。

extends: This option has been removed for version: "3.x" Compose files. (For more information, see Extending services.)

和訳: このオプションはバージョン: 3.xでは削除されています。

実際にV3で使おうと思ったら、こんなエラーが出まくりで動く気配がない。

$ docker-compose ps
ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.db: 'extends'

この機能を一時的にONにしようとdocker-compose.ymlの先頭行をservice: "2"に変更しても、
参照先のファイルがV3準拠の場合は「お前V3のdocker-composeを参照しようとしてるだろ!小手先の事をしてもダメだぞ!」と叱られてしまう。

「V3で無くなったextendsに関しては復活の可能性を議論しています」みたいなIssueを見つけた。
Add support for extends feature in Compose v3 / docker stack deploy #31101

ざっとIssueを流し読みしたところ、
extendsはそもそもバギーだし、依存関係含めると中々対応が難しいという問題があった。
それでV3で削除してフラットなデータ構造にしてねという対応にしたらしい。

当然非難轟々で「受け皿がない」「コピペだらけになるだろ」「もうdocker-compose.ymlを自動生成するスクリプト作ったわ」という感じで荒れに荒れている。

因みにV3に於けるextendsを公式のドキュメントで調べると、
「削除されました」というワードにたどり着くだけで散々たらい回しにされてしまう。
これに関しても利用者はブチ切れており、下記のお叱りのコメントが付いている。

Not only this, but the changelog says "this has been removed, see 'how to upgrade' for details". I look at "how to upgrade" for, you know, details on how to upgrade, and what that says is "see 'extending services' for details". I go to "extending services" figuring I'll finally see a way to extend my files, only to see "this has been removed, see the changelog for details".
At this point, this seems like a cruel joke the documentation writer is playing.

意訳: V2からのアップデートに追従するにはAをご覧ください、Aに行くとBをご覧ください、そして最後にはAをご覧くださいに戻る。こんな下らん言葉遊びをドキュメントに書くな。

DockerComposeの拡張フィールド使う案が2018/8に出ているが、これは本格的な実装はまだまだ先っぽい?

完全にextendsと同じことがやりたいなら、docker-compose.ymlファイルを全てV2相当まで落とすか、
自分でスクリプトを作って自動的に生成する手段を取るしかなさそう。

追記: V3でもMultiple Compose filesを使う事で代用可能

extendsはなくても代用はできそうだ。
Multiple Compose filesに関しての記載がある記事を見つけたので追記。
参考記事: docker-compose.ymlをDRYに書くテクニック2選 - @reireias

この「Multiple Compose files」セクションがとても参考になる。

docker-composeは「docker-compose.override.yml」ファイルを用意したり、
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -dなどと記述することで複数のYAMLファイルをマージしながら起動出来る仕組みが存在するようだ。

ベースとなるdocker-compose.ymlは上書き上等レベルのシンプルさで記述しておき、
Makefileやshell-script、package.jsonなんかに書いて管理するというのがベストプラクティスになるだろう。

ただしYAMLファイル同士全体のマージが前提となる。
V2が出来ていたextendsみたいに、あちこちのファイルから少しずつついばむような指定は出来ない。

そこが少々不便ではあるものの、
docker-compose.ymlはシンプルにしましょうねって事を心がければ
その違いが大きな問題になることはほとんど無いと思う。

31
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?