複数のdocker-compose.ymlを使って、設定の追加や上書きをやってみる
知識として知っているだけで実際に使ったことはない←

要約
Docker Composeの設定ファイルは複数指定できて、設定の追加や上書きができる。
早速詳細に見ていきましょう↓
docker-compose.ymlは複数指定可能
docker compose up実行時に-fオプションを使うことで、
参照するdocker-compose.ymlファイル(設定ファイル)を指定できることは、ご存知の方も多いと思います。
しかし、複数の設定ファイルを指定できることはあまり知られていないと思います(勝手な決めつけ)。
Docker-docs-ja では、以下のページで説明がされています。
『ファイル間、プロジェクト間での Compose 設定の共有 』
実際の動きを見てみる
以下のようなdocker-compose.ymlを用意します。
docker-compose.yml
version: '3'
services:
  web:
    image: "nginx:latest"
docker compose -f docker-compose.yml upでコンテナを起動した後に、
ブラウザを開いてhttp://localhost/にアクセスしてみます。

Webサイトにアクセスできませんでした。
ポートを公開していないので当然の結果ですね。
次に、以下のようなdocker-compose.override.ymlを用意します。
docker-compose.override.yml
version: '3'
services:
  web:
    ports:
      - "80:80"
そして、今度は以下のようにして、複数の設定ファイルを指定します。
docker compose -f docker-compose.yml -f docker-compose.override.yml up
では、http://localhost/にアクセスしてみます。

今度は無事にアクセスできました。
ポート公開がうまくできているようです。
上記の挙動を見ることで、docker-compose.ymlで使用イメージの指定ができており、なおかつ、
docker-compose.override.ymlでポート公開の設定ができていることが分かります。
すなわち、Docker Composeは追加で設定ファイルを指定することで、設定を追加できます。
なお、今回はサンプルを省きましたが、追加だけではなく、上書きも可能です。
(後ほど出てくるサンプルを見れば、上書きの挙動も分かると思います)
重複した設定項目がある場合はどちらが優先される?
前章の最後に、「追加だけではなく、上書きも可能です」と書きました。
本章では、複数の設定ファイルを指定したさいに、 例えば、同じ環境変数名に対して異なる値を設定していた場合どちらの設定が優先されるのかを解説します。
はじめに、ドキュメントを読んでみます。
『設定の追加と上書き』 の章に、
設定オプションが元々のサービスとローカルのサービスの両方にて定義されていた場合は、 元のサービスの値はローカルの値によって置き換えられるか、あるいは拡張されます。
とありますが、元のサービスってどっち?となります。
なので、実際に動作を見てみます。
以下のファイルを用意します。
main.go
package main
import (
	"fmt"
	"os"
)
func main() {
	fmt.Println(os.Getenv("ENV"))
}
docker-compose.yml
version: '3'
services:
  app:
    image: "golang:latest"
    working_dir: /app
    volumes:
      - .:/app
    environment:
      - ENV=local
    command: "go run /app/main.go"
docker-compose.override.yml
version: '3'
services:
  app:
    environment:
      - ENV=prod
docker compose upするとGoのコードが動いて、環境変数ENVの内容が表示されるようになっています。
まずは、docker compose -f docker-compose.yml -f docker-compose.override.yml upしてみます。
結果は以下のとおりです。
[+] Running 1/1
 ⠿ Container test-app-1  Recreated                                                                                                                      0.1s
Attaching to test-app-1
test-app-1  | prod
test-app-1 exited with code 0
4行目でprodと表示されていますね。
これはdocker-compose.override.ymlで設定した内容です。
よって、ドキュメントの言葉に当てはめると、
元々のサービス = docker-compose.ymlで定義したサービス
ローカルのサービス = docker-compose.override.ymlで定義したサービス
となるので、docker-compose.ymlの内容がdocker-compose.override.ymlの内容で上書きされていることになります。
では、次はファイルの指定順を逆にしてみます。
docker compose -f docker-compose.override.yml -f docker-compose.yml up
結果は以下のとおりです。
[+] Running 1/1
 ⠿ Container test-app-1  Recreated                                                                                                                      0.1s
Attaching to test-app-1
test-app-1  | local
test-app-1 exited with code 0
localと表示されました。docker-compose.override.ymlの内容がdocker-compose.ymlの内容で上書きされたということですね。
以上、2つの検証から分かったことをまとめると、以下のとおりです。
- 元々のサービスの値はローカルのサービスの値によって上書きされる
- 元々のサービス = 先に指定した設定ファイルの内容
 - ローカルのサービス = 後から指定した設定ファイルの内容
 
 
ユースケース
本機能のユースケースに関しては、ドキュメントに詳しく記載があるので、そちらをご覧ください。
『利用例』
の項です。
ちなみに今回の機能に関して、現状、僕はdocker-composeをローカルでしか使っていないのに加えて、 OSによる差分で困るといったこともなかったので使ったことはありません。
まとめ
Docker Composeの設定ファイルは複数指定することで、設定の追加や上書きが可能です。
重複している設定内容については、先に指定した設定ファイルの内容が後に指定した設定ファイルの内容で上書きされます。



