hogashi.*

日記から何から

Docker Compose 1.27.0以降ではdocker-compose.ymlにversionを書く必要がなくなっていた

あらすじ

 docker-compose.yml でトップレベルの version 要素を指定していると、 WARN[0000] (...)/docker-compose.yml: `version` is obsolete と表示される。インターネットを見ていくと version は指定しなくて良い、消したらいい、という記事がたくさん出てくるし、たしかに公式のドキュメントにも obsolete と書かれている Version and name top-level elements | Docker Docs

Version top-level element (obsolete)
The top-level version property is defined by the Compose Specification for backward compatibility. It is only informative and you'll receive a warning message that it is obsolete if used.

https://docs.docker.com/compose/compose-file/04-version-and-name/

 しかし昔は必要だった記憶があって、気になって issue/p-r を見ていったら、 2020年あたりにはすでに optional になっていたようだった。

時系列

提案

 version を書くのをやめよう、という issue はこれ Validate compose file on supported API, not version · Issue #7201 · docker/compose
 大まかに書くと「Docker エンジンの API バージョンと docker-compose.yml のバージョンの食い違いによるエラーや、妙に古い記述から version をコピペしていて yml のパースに失敗するなど、色々問題が起きている。 docker-compose.yml の version の記述をやめ、とにかく Docker エンジンの API バージョンを参照して判断することにすれば、解決できるはずだ」という提案。結局実行するときにはエンジン側で対応している API しか使えないのだから、そっちのバージョンだけを真として扱うのが良いだろう、というのはわかりやすいし確かに感がある*1

仕様の変更

 この内容が Compose Spec community という場所で議論され Don't require version · Issue #13 · compose-spec/compose-spec 、話し合いの結果 (2020/6/4 に) 受理されている。議論のすべてが issue 上に載っているわけではなさそうに見える (激論中に突然受理されているみたいになっている) けど、「破壊的変更をしたくなることは未来永劫ないのか」「逆にどの機能が使えるのかわかりづらくないか」みたいなことが議論されていそう。

 この結果、仕様が変更され Make `version` optional and define strict/standard/loose parsing mode by ndeloof · Pull Request #82 · compose-spec/compose-spec 、 version は後方互換性のために書けるが、単に付記する情報くらいの扱い (この値を使って何かするわけではない) 、ということになっている。

  ## Version top-level element

- A top-level version property is required by the specification. Version MUST be 3.x or later, legacy docker-compose 1.x and 2.x are not included as part of this specification. Implementations MAY accept such legacy formats for compatibility purposes.
+ Top-level `version` property is defined by the specification for backward compatibility but is only informative. 
https://github.com/compose-spec/compose-spec/pull/82/files#diff-bc6661da34ecae62fbe724bb93fd69b91a7f81143f2683a81163231de7e3b545
実装の変更

 docker-compose の実装のほうで version を optional にするのはこの p-r でやっていて Merge V2 - V3 compose file formats (optional version field) by aiordache · Pull Request #7588 · docker/compose v2, v3 の docker-compose.yml のスキーマを一緒にしようという趣旨になっている。 master ブランチにマージされたのは 2020/7/27 。
 version に書かれたバージョンの値ごとにスキーマを確認するのではなく、とにかくひとつのスキーマを真とするようになったので、 compose/config/config_schema_v2.0.json, compose/config/config_schema_v2.1.json, ... みたいなファイルが全部消えて compose/config/config_schema_compose_spec.json に統一されているのが感動的 (v2 と v3 もまとめられていることがわかる)。

 この変更は (1.27.0-rc1 を経て) Release 1.27.0 · docker/compose で 2020/9/7 にリリースされている (リリースノートの 1.27.0 の内容にも同じことが書かれている)。以来 version は書かなくてよい状態だったのか……。

  • Merge 2.x and 3.x compose formats and align with COMPOSE_SPEC schema
https://github.com/docker/compose/releases/tag/1.27.0

 しかしいつから `version` is obsolete の warn が出ていたのかはよくわからなかった。 2020年ごろにこの warn を見た覚えがないけど、本当に出てなかったのか単に warn を見過ごしていたかあんまり自信がない。インターネットを見るとなんとなく 2024年の情報が多いので、最近のどこかのバージョンでちゃんと warn が出るようになったのかな……。

ちなみに

 docker-compose.yml と書き続けてきたけど、実は今は設定ファイル (Compose file) のファイル名は compose.yaml が推奨されている *2。 拡張子は yml でも大丈夫で、 docker-compose.yaml (.yml) も後方互換性のために動くようになっている。公式のドキュメントはこれ https://docs.docker.com/compose/compose-application-model/#the-compose-file

The default path for a Compose file is compose.yaml (preferred) or compose.yml that is placed in the working directory. Compose also supports docker-compose.yaml and docker-compose.yml for backwards compatibility of earlier versions. If both files exist, Compose prefers the canonical compose.yaml.

https://docs.docker.com/compose/compose-application-model/#the-compose-file

*1:一応 1.x 系では version の記述を使っていた、とは付記されていそうで、 2.x 以降になってから不要にできるようになった、と書かれていそう? だけどこのあたりはあまり読み取れなかった

*2:p-r でいうとこのあたり Update README.md to use standard `compose.yaml` file name by johnthagen · Pull Request #11233 · docker/compose