Docker Composeのextendsで共通設定を複数ファイルに分割管理する方法|環境別オーバーライドとの使い分け

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > Docker Composeのextendsで共通設定を複数ファイルに分割管理する方法|環境別オーバーライドとの使い分け
「複数のcompose.ymlに同じservice定義をコピペしていて、片方だけ直し忘れて事故った」
「開発用と本番用でビルド設定やログ設定だけ違うのに、サービス定義を丸ごと2重管理している」
そんな悩みを抱えたままcompose.ymlを運用しているチームは少なくありません。

Docker Composeには、共通のサービス定義を別ファイルに切り出し、複数のサービス・複数のプロジェクトから再利用できるextendsという仕組みがあります。
公式ドキュメントでの扱いが小さく、「override(環境別の設定上書き)」との違いを理解しないまま使うと、意図しない設定崩れを招くことがあります。

この記事では、extendsの基本構文から共通base定義を切り出す実践例、override(docker-compose.override.yml)との使い分け、設定が反映されない時のトラブルシュートまで、実サーバーの確認例を交えて解説します。

動作確認環境: Rocky Linux 9.4 / Ubuntu 24.04 LTS(Docker Engine 26.x・Docker Compose Plugin v2.27)

この記事のポイント

・extendsは共通のサービス定義を別ファイルに切り出し、複数サービス・複数プロジェクトから再利用する仕組み
・override(docker-compose.override.yml)は同一プロジェクト内の環境差分、extendsは共通化そのものが目的で役割が違う
・Composeのマージ規則では、ports・volumesなどのリスト項目は結合ではなく丸ごと置き換えになる点が事故の原因になりやすい
・docker compose configで結合後の設定を出力し、意図した内容にマージされているかを毎回確認するのが鉄則


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

extendsとは何か|Compose Specにおける共通設定の継承の仕組み

複数のマイクロサービスを1つのcompose.ymlで管理していると、ロギング設定やヘルスチェック、リスタートポリシーなど「どのサービスにも共通して書きたい項目」が増えていきます。
これをサービスの数だけコピペしていると、設定変更のたびに全サービスを1つずつ直す必要が出てきて、修正漏れの温床になります。

1. なぜcompose.ymlが肥大化するのか

現場でよくあるのは、開発チームが増えるにつれてサービス数が10・20と増え、logging:healthcheck:restart:といった定型ブロックがサービスごとに重複していくパターンです。
1箇所を直し忘れると、本番だけログ設定が古いままになるといった実務上の事故につながります。

2. extends構文の基本形

extendsは、file:で参照先ファイル、service:で参照先サービス名を指定し、そのサービス定義をベースに継承します。

# extendsの最小構文 services: web: extends: file: common-services.yml service: app-base ports: - "8080:80"

webサービスはcommon-services.yml内のapp-baseサービスの定義(イメージ・環境変数・ヘルスチェック等)を継承したうえで、ports:だけを自分で上書き追加します。

extendsで共通base設定を複数サービスに継承する実践例

3. common-services.ymlに共通設定を切り出す

まず、複数サービスで共有したい設定だけを独立したファイルにまとめます。

# common-services.yml(共通設定の置き場) services: app-base: image: myapp:latest environment: - TZ=Asia/Tokyo - LOG_LEVEL=info logging: driver: json-file options: max-size: "10m" max-file: "3" healthcheck: test: ["CMD", "curl", "-f", "http://localhost/healthz"] interval: 30s timeout: 5s retries: 3 restart: unless-stopped

続いて、各サービス側のcompose.ymlからapp-baseを継承します。

# compose.yml(本体:web/workerがapp-baseを継承する) services: web: extends: file: common-services.yml service: app-base ports: - "8080:80" worker: extends: file: common-services.yml service: app-base command: ["python", "worker.py"]

webworkerは、ロギング設定(json-file・10MB×3世代)やヘルスチェック、リスタートポリシーを個別に書かずに共有できます。
共通部分を1箇所に集約したことで、ログ設定を変更したい場合はcommon-services.ymlを1回直すだけで両方に反映されます。

4. docker compose configで継承結果を確認する

extendsは「マージ後の見えない設定」が増える仕組みなので、実際にどうマージされたかを都度確認する習慣が重要です。

# 結合後の実効設定をYAMLで出力して確認する $ docker compose config services: web: environment: LOG_LEVEL: info TZ: Asia/Tokyo healthcheck: interval: 30s retries: 3 test: - CMD - curl - -f - http://localhost/healthz timeout: 5s image: myapp:latest logging: driver: json-file options: max-file: "3" max-size: 10m ports: - mode: ingress target: 80 published: "8080" restart: unless-stopped

docker compose configは本番投入前の確認作業として必ず実行すべきコマンドです。継承ミスや意図しない上書きは、ほとんどがこの1コマンドで事前に発見できます。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Docker Composeの設計・共通化をはじめとするDockerの実践スキルを体系的に学べる講座を用意しています。
Dockerマスター講座の詳細はこちら >>

extendsとoverride(compose.override.yml)の違いと使い分け

5. overrideは「環境差分」、extendsは「共通化」が目的

似たような仕組みに見えて、extendsとoverrideは目的がまったく違います。
override(docker-compose.override.ymlや-f複数指定):同一プロジェクトの中で「開発環境だけvolumesをbind mountにしたい」「本番だけレプリカ数を増やしたい」といった環境差分を後から重ねる仕組み
extends:プロジェクトやファイルをまたいで「共通のベース定義」そのものを1箇所に集約し、複数サービスから参照する仕組み

overrideは「同じプロジェクトの縦の差分」、extendsは「複数サービス・複数プロジェクトの横の共通化」と整理すると混同しにくくなります。

6. 両方を組み合わせた設計パターン

実務では両者を併用するのが一般的です。共通のapp-base定義はextendsで集約し、環境ごとの差分はoverrideで重ねます。

# compose.override.yml(本番のみポート・レプリカ数を変更する差分) services: web: ports: - "443:80" deploy: replicas: 3

# 本番環境ではoverrideファイルを明示的に指定して起動する $ docker compose -f compose.yml -f compose.override.yml up -d

extendsで「何を共有するか」を固定し、overrideで「どこを環境ごとに変えるか」を分離すると、compose.ymlの見通しが大きく改善します。

トラブルシュート|extendsで設定が反映されない時の調査手順

7. 手順1: リストのマージではなく置き換えになっていないか疑う

extendsやoverrideでは、Compose全体のマージ規則が適用されます。
environment:のようなマッピング(連想配列)はキー単位でマージされますが、ports:volumes:のようなリストは結合ではなく丸ごと置き換えになります。
これに気づかず「継承元のvolumesも残るはず」と思い込んでいると、共通base側で定義したマウントがごっそり消えるという事故が起きます。

# app-base側のvolumes(共有ライブラリのマウント) services: app-base: volumes: - shared_lib:/opt/shared # web側でvolumesを追加したつもりが、実際は置き換わってしまう例 services: web: extends: file: common-services.yml service: app-base volumes: - ./web-static:/var/www/static # ← ここに shared_lib のマウントを書き足さないと消える

注意:共通base側のvolumesやportsを引き継ぎたい場合は、継承側でも同じ項目を明示的に書き足す必要があります。「継承すれば自動的に足し算になる」という思い込みが最も多い事故原因です。

8. 手順2: docker compose config --servicesとpsで実際の反映状況を確認する

# 認識されているサービス一覧を確認(extends先のservice名の誤字はここで発覚しやすい) $ docker compose config --services web worker db # 起動中コンテナの実際のマウント・ポート状況を確認 $ docker compose ps --format "table {{.Name}}\t{{.Ports}}" NAME PORTS myapp-web-1 0.0.0.0:8080->80/tcp myapp-worker-1

9. 手順3: 参照ファイルのパスミスを疑う

extends.file:のパスは、それを記述しているcompose.ymlからの相対パスで解決されます。
サブディレクトリに移動した際にパス指定を直し忘れると、以下のようなエラーで起動そのものが失敗します。

$ docker compose up -d service "web" refers to undefined service "app-base": could not find common-services.yml # 対処: extends.fileのパスを実際のディレクトリ構成に合わせて修正する extends: file: ../shared/common-services.yml service: app-base

10. よくある原因チェックリスト

リスト項目の消失:ports・volumesなど継承元にあった設定が、継承側の同項目で丸ごと置き換わっていないか
service名の誤字:extends.serviceに指定した名前が参照先ファイル内のサービス名と一致しているか
相対パスのズレ:extends.fileのパスが、compose.ymlの実際の配置場所から見て正しいか
循環参照:AがBを継承し、BがAを継承するような循環構成になっていないか(Composeはこれを検出してエラーにする)
本番反映前の未確認:docker compose configで実効設定を確認せずに本番へupしていないか

本記事のまとめ

やりたいこと 使う仕組み・確認コマンド
共通のサービス定義を複数サービスで使い回したい 共通ファイルを作りextends.file/serviceで継承する
開発・本番で一部だけ設定を変えたい docker-compose.override.ymlや-f複数指定で重ねる
継承後の実際の設定を確認したい docker compose configで実効設定を出力する
継承元のvolumes・portsが消えてしまう リストは置き換えのため、継承側にも明示的に書き足す
extends先のファイルが見つからないと言われる extends.fileの相対パスを配置場所に合わせて修正する
extendsは正しく使えば、共通設定の二重管理をなくし、compose.ymlの保守性を大きく高めてくれる仕組みです。
一方で「リストは結合ではなく置き換え」というマージ規則を知らずに使うと、静かに設定が欠落する事故につながります。
本番へ反映する前に必ずdocker compose configで実効設定を確認する運用を、チームのルールとして定着させておきましょう。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、本記事で紹介したDocker Composeの共通化・環境分離設計をさらに深く学べる講座を用意しています。
Dockerマスター講座の詳細はこちら >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。