Windows で Docker Compose を使おうとして「The system cannot find the file specified.」エラーが出て困っている人を何人か見たので、まとめておく。
ケース
Docker Compose の設定ファイルのうち、環境変数だけを別ファイルとして切り出したいケースを考える。
services:
app:
(略)
services:
app:
environment:
API_KEY: ...
COMPOSE_FILE=compose.dev.yml:compose.env.yml
ここで docker compose
コマンドを使用すると、まず Docker Compose は .env
ファイルを読んで環境変数として扱ってくれるので、環境変数 COMPOSE_FILE
が解釈されて -f compose.dev.yml -f compose.env.yml
オプションを付けたときと同じ振る舞いになる。Docker Compose は設定ファイルが compose.dev.yml
と compose.env.yml
の2つであることがわかるので、Docker Compose はこの2つを順番に読み込んでコンテナを起動してくれる。
Windows ではエラーが発生する
上記のケースは Linux や macOS では問題なく動くが、Windows では下記のエラーが発生する。
The system cannot find the file specified.
どうやら compose.dev.yml:compose.env.yml
という1つのファイルを読み込もうとして「そのようなファイルはない」と言っている。つまり :
によるパスの分割がされていない。
Docker Compose の公式ドキュメント を読むと、このように書いてある。
Default separator: When specifying multiple Compose files, the path separators are, by default, on:
- Mac and Linux: : (colon),
- Windows: ; (semicolon).
Windows ではパスの区切り文字は ;
を使わないといけないらしい。
なぜ区切り文字が異なるのか
この話に限らず、慣習的に Unix 系 OS ではパスの区切り文字は :
が使われ、Windows では ;
を使われる。(環境変数 PATH
など)
おそらく Windows ではドライブレター (C:
など) に :
が使われるため、ファイルパスの区切り文字として :
を使うことができないという事情があるのだろう。
解決策1: 環境変数を書き換える
最も簡単な解決策としては、 .env
ファイルを書き換えてしまい、区切り文字を ;
に変更すればよい。Windows でしかそのリポジトリを触らないのであればそれで問題はない。
しかし Windows でも macOS でも同じリポジトリを動かしたく、かつ .env
ファイルをリポジトリで管理している場合は「どちらか片方でしか動かない」という問題が発生する。
解決策2: 区切り文字を変更する
環境変数 COMPOSE_PATH_SEPARATOR
を指定すると、パスの区切り文字を変更することができる。
COMPOSE_FILE=compose.dev.yml:compose.env.yml
COMPOSE_PATH_SEPARATOR=:
これで Windows でも macOS でも同じリポジトリの .env
ファイルを使用して Docker Compose を使うことができる。