雰囲気でDocker Composeを触っている状態から脱するために調べたこと(2023)

エンジニアの岡村です。

自分はサーバーがメインではなく、あまり業務でガッツリ触るわけでもないのですが、最近それなりに活用するようになってきました。しかし、ネット上の日本語情報を読んでいるだけではこれの書き方が正しいのかよく分からない、と悩むことが結構あったため、色々情報を漁ってみました。 この記事は、特に自分が気になった部分の調べた結果を記事に纏めてみたものです。対象読者はdocker-composeを雰囲気でupやdownは叩けるけどComposeファイルの書き方がよく分からんとなってる人です。

Docker Composeの概要とcompose.yaml、Compose Specの関係

docker-composeは複数のコンテナが連携して動作する、コンテナベースのアプリケーションを構築する仕組みです。動作させるにはcompose.yamlという構成ファイルを記述し、Docker composeに読み込ませます。

最新のcompose.yamlを書くにあたっては、Compose Specという概念が関わってきます。Compose Specは、プラットフォームに依存しない、マルチコンテナベースのアプリケーションを定義する為の標準仕様です。所謂HTML Living Standardのようなもので、Compose Specでcompose.yamlをどのように書くべきか、書かれたものがどの様に動作するべきかが定義されています。

ここでのプラットフォームとは、Docker ComposeやAWS、Azureなどを指します。Compose Specでは、定められた仕様を各プラットフォームが実装することを想定しており、compose.yamlを読み込み動作させるアプリをDocker Composeに限定していない様です。

compose-spec.io

Dockerのドキュメントの日本語訳等でCompose 仕様という言葉が出たらこのCompose Specの事を指しています。

compose.yamlの書き方は Compose Specに準拠すればOK

Docker Engine 19.03.0+ 及び Compose 1.27.0+ であれば、Compose Spec形式のcompose.yamlがサポートされています。ただし、Compose Specに関しては明確にバージョンが切られているわけではないので、Docker Composeのバージョンが古ければ一部の属性がサポートされていない可能性があります。

docs.docker.com

blog1.mammb.com

ちなみに、古いバージョンとCompose Specとの関係は以下のようになっています。

  • Compose V1 -- 最初期の、docker composeがdocker-composeとして、dockerとは独立したアプリとして開発されており、Compose Specもない頃のものです。非推奨のラベルがついている他、2023年6月末に全てのバージョンのDocker Desktopから削除され、使用できなくなるとアナウンスされているため、使用するべきではありません。手元のファイルがCompose V1の仕様で書かれているのであれば、引き続き使用するには変換作業が必要です。

  • Compose V2 及び Compose V3 -- Compose Specへの準拠を行った新しいバージョンのComposeファイルです。元々V2、V3...とバージョンを進めていく予定だったのが、Compose Specに統合された様です。

Compose Specの場所

GitHubにあります。RFC2119に準拠した文章になっている為、読みやすく明確になっており、最新の仕様を追うだけであれば、こちらを読んでおけば問題なさそうです。

github.com

これ以降は自分がCompose Specとその歴史的背景にたどり着くまでの間、特に気になってた部分に関して、ちょっとした解説を交えて紹介していきます。

推奨のファイル名はcompose.yaml

(GitHub上で)圧倒的に使われているのはdocker-compose.ymlですが、Compose Specではcompose.yamlが推奨されています。

spec.md#compose-file

手元で試してみたところ(compose v2.15.1)、composeファイル名が指定されていない時は以下の順番でファイルが選ばれました。

  • compose.yaml(最優先)
  • compose.yml
  • docker-compose.yml
  • docker-compose.yaml

元々はdocker-compose.ymlがデフォルトだったのですが、2020年初頭に変更されたようです。

github.com

dockerという名前がベンダー固有のものであり、一方で前述の通りCompose SpecはDockerに依存しないものであるからという理由で変えたみたいですね。

compose.yaml内にバージョンを記述するのは非推奨

最新の仕様では、ファイル内にバージョンを記述することは非推奨となっています。

spec.md#version-top-level-element

Compose Specによると、下位互換性の為に残されていますが、実装においてバージョン情報を参照して動作を変更する様なことはすべきではなく、そのアプリがリリースされた時点での最新のCompose Specに従うべきと書かれているため、version要素によって挙動が変化することはなさそうです。

Compose V1もバージョンを指定しないので、Compose V1とCompose Specのファイルが混同されそうな気がしますが、Compose V1はサポートを終了するので問題ないという判断をしたのでしょうか?

環境変数の定義方法は2種類あるがどちらでもOK

以下の様に、環境変数の定義はリストだけではなく辞書形式でも書けるようになっています。

# リスト形式
    environment:
      - KEY=VALUE
      - KEY2=VALUE2
      - KEY3=123
# 辞書形式
    environment:
      KEY: VALUE
      KEY2: 'true'
      KEY3: '123'

spec.md#environment

個人的にはGitHub Actionsと同じように書けて、yamlのハイライトも効くので読みやすい後者の方が好きです。ただし文字列しか受け付けないので、true等のyamlで意味を持つ文字はクウォートで囲んでやる必要があります。

docker-composeコマンドとdocker composeコマンドは後者の方が新しい

docker-composeコマンドはV1の時代からありましたが、docker composeコマンドはV2(Compose Spec)時代に新しく作られました。

differences-between-compose-v1-and-compose-v2

docker composeコマンドの方がCompose Specに準拠しており、クラウドプラットフォームへのデプロイなどが行えるようです。

最新版ではどちらのコマンドも利用可能です。Compose V1のサポートが終了しても、docker-composeコマンドはエイリアスとして残し続ける方針のようです。

(おまけ)Windows環境における改行コードの問題とその対策

最後に脱線ですが、Dockerをwindowsで動かすときは改行コードをlfに統一しましょう。 そうしないと、linuxコンテナを動かすときに改行コードで消耗することになります。

auto-crlfを無効化しましょう。

git config --local core.autocrlf input

ついでにcompose.yamlと同じ階層に.editorconfigファイルも設置しておきましょう。

root = true
[*]
end_of_line = lf
insert_final_newline = true

終わり

Compose Specとその歴史的背景を把握したことで、だいぶ認識がスッキリした様に思います。これで安心して絶望の谷に落ちていくことができそうです。