ファイル間、プロジェクト間での Compose 設定の共有
読む時間の目安: 6 分
Compose がサポートする設定共有には 2 つの方法があります。
- Compose ファイル全体を 複数の Compose ファイルの利用 により拡張します。
- 個々のサービスを
extends
フィールド を使って拡張します(Compose ファイルバージョン 2.1 まで)。
複数の Compose ファイルの利用
Compose ファイルを複数利用することにすれば、Compose によるアプリケーションを異なる環境、異なる作業フローに合わせてカスタマイズできます。
Compose ファイルが複数ある意味
デフォルトにおいて Compose は 2 つのファイルを読み込みます。
docker-compose.yml
と、必要に応じて編集するdocker-compose.override.yml
です。
慣習としてdocker-compose.yml
には基本的な設定を含めます。
docker-compose.override.yml
ファイルは、オーバーライドという表現が含まれていることから分かるように、既存のサービスあるいは新たに起動する全サービスに対しての上書き設定を行うものです。
サービスの定義が両方のファイルに存在した場合、Compose は 設定の追加と上書き に示すルールに従って定義設定をマージします。
複数の上書きファイルがある場合、あるいは上書きファイルが 1 つであってもその名前を別にしている場合、-f
オプションを使って、ファイル名を列記して指定することができます。
Compose はコマンドライン上に指定された順に、設定ファイルをマージします。
詳細は docker-compose
コマンドリファレンス の-f
オプションに関する情報を参照してください。
複数の設定ファイルを利用する場合、各ファイルに記述されるパスは、基準となる Compose ファイル(1 つめの-f
により指定された Compose ファイル)からの相対パスである必要があります。
これは上書きするファイルが Compose ファイルとして有効である必要がないからです。
上書きファイル内は、設定項目が部分的に含まれているだけで構いません。
サービスに対する定義部分がどのパスからの相対パスとして定義されているのかといったことを追っていくのは、なかなか難しく理解しづらくなります。
そこでパスを理解しやすくするために、パス指定はすべて、ベースとなるファイルからの相対パスとして定義するものとしています。
利用例
この節では複数の Compose ファイルを利用する標準的な例を 2 つ示します。 1 つは Compose アプリを異なる環境向けに切り替えるもの。 もう 1 つは Compose アプリに対して管理タスクを実行するものです。
異なる環境向けの例
複数の設定ファイルを利用する例としてよくあるのは、開発環境向けの Compose アプリを、本番環境向けなど(本番環境、ステージング環境、CI 環境など)に切り替える場合です。 こういった環境の違いに対応するには、Compose 設定ファイルをいくつかの設定ファイルに切り分けて行います。
まずはサービスの標準設定を行うベースファイルから始めます。
docker-compose.yml
web:
image: example/my_web_app:latest
depends_on:
- db
- cache
db:
image: postgres:latest
cache:
image: redis:latest
この開発環境向け設定の例では、ホストに対してポートをいくつか公開し、ソースコードをボリュームとしてマウントした上で、ウェブイメージをビルドしています。
docker-compose.override.yml
web:
build: .
volumes:
- '.:/code'
ports:
- 8883:80
environment:
DEBUG: 'true'
db:
command: '-d'
ports:
- 5432:5432
cache:
ports:
- 6379:6379
docker-compose up
を実行すると、上書き用の設定ファイルが自動的に読み込まれます。
この Compose アプリは、このままでも十分に本番環境向けとすることができます。 ただここでは、別の上書きファイルを生成します(このファイルは別の git リポジトリに含まれているとか、別の開発チームが管理するものであるかもしれません)。
docker-compose.prod.yml
web:
ports:
- 80:80
environment:
PRODUCTION: 'true'
cache:
environment:
TTL: '500'
この本番環境向け Compose ファイルをデプロイするために、以下を実行します。
$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
これによって 3 つのサービスすべてがデプロイされますが、利用される設定はdocker-compose.yml
とdocker-compose.prod.yml
から読み込まれたものです(docker-compose.override.yml
内の開発環境向け設定は利用されません。)。
本番環境での Compose 利用に関する情報は、本番環境での Compose の利用 を参照してください。
管理タスクの例
よく行われるもう 1 つの例は、Compose アプリにおけるサービスに対して、特別なタスクあるいは管理タスクを実行する場合です。 ここでは、データベースバックアップを実行する例を示します。
docker-compose.yml から始めます。
web:
image: example/my_web_app:latest
depends_on:
- db
db:
image: postgres:latest
docker-compose.admin.yml において、新しいサービスを追加して、データベースのエクスポートまたはバックアップを行うようにします。
dbadmin:
build: database_admin/
depends_on:
- db
通常の環境を起動するときはdocker-compose up -d
を実行します。
またデータベースバックアップを実行するときは、docker-compose.admin.yml
も含めるようにして実行します。
$ docker-compose -f docker-compose.yml -f docker-compose.admin.yml \
run dbadmin db-backup
サービスの拡張
メモ
キーワード
extends
は、かつての Compose ファイルフォーマットバージョン 2.1 までにおいてサポートされます。 (バージョン 2 における extends を参照のこと。) これは Compose バージョン 3.x ではサポートされていません。 キーワードの追加、削除に関しては バージョン 3 のまとめ や アップグレード方法 を参照してください。 また moby/moby#31101 では、将来のバージョンにおいて何らかの形式でextends
をサポートする可能性について議論するスレッドがありますので、確認してみてください。 キーワードextends
は、docker-compose のバージョン 1.27 およびそれ以降から含まれるようになりました。
Docker Compose のextends
キーワードを使うと、さまざまな設定ファイルに共通する内容を共有することができます。
それはまったく別のプロジェクト間でも可能です。
ごく標準的な設定オプションを再利用しているサービスがいくつもある場合に、このサービス拡張機能を活用することができます。
extends
を使って標準的なサービスオプションを 1 箇所に定義しておけば、それをどこからでも参照することができます。
volumes_from
、depends_on
は、extends
を利用したサービス間での共有はされません。
これらが例外となっているのは、気づかないうちに依存関係が発生してしまうことを避けるためです。
volumes_from
はいつもローカルな定義に利用するものです。
こうしているからこそ、そのときの設定ファイルを読めば、サービス間の依存関係がはっきりわかることになります。
ローカルに定義しておくのは、参照されている側のファイルに変更が加わっても、影響がなく済むことにもつながります。
extends によるサービス拡張設定の理解
docker-compose.yml
内にサービスを定義するときには、どのようなサービスであっても、別のサービスを拡張するように宣言できます。
たとえば以下のとおりです。
services:
web:
extends:
file: common-services.yml
service: webapp
上の設定は Compose に対して、common-services.yml
ファイル内に定義されているwebapp
サービスの設定を再利用することを指示しています。
common-services.yml
は以下のようになっているとします。
services:
webapp:
build: .
ports:
- "8000:8000"
volumes:
- "/data"
この例では、docker-compose.yml
ファイル内のweb
の直下に、build
、ports
、volumes
の設定を行った場合と同じ結果を得ることができます。
さらにdocker-compose.yml
内には、ローカルでの設定内容を定義あるいは再定義することができます。
services:
web:
extends:
file: common-services.yml
service: webapp
environment:
- DEBUG=1
cpu_shares: 5
important_web:
extends: web
cpu_shares: 10
また他のサービスを記述して、web
サービスからそのサービスへリンクすることも可能です。
services:
web:
extends:
file: common-services.yml
service: webapp
environment:
- DEBUG=1
cpu_shares: 5
depends_on:
- db
db:
image: postgres
利用例
複数のサービスを利用していてそこに共通設定が存在する場合に、単独のサービスを拡張することができるかもしれません。 以下の例では Compose アプリにおいて 2 つのサービスがあります。 ウェブアプリケーションとキューワーカー(queue worker)です。 この 2 つのサービスは同一のコードを用いるものであり、多くの設定オプションを共有します。
common.yml では共通する設定を定義します。
services:
app:
build: .
environment:
CONFIG_FILE_PATH: /code/config
API_KEY: xxxyyy
cpu_shares: 5
docker-compose.yml では、上の共通設定を利用する具体的なサービスを定義します。
services:
webapp:
extends:
file: common.yml
service: app
command: /code/run_web_app
ports:
- 8080:8080
depends_on:
- queue
- db
queue_worker:
extends:
file: common.yml
service: app
command: /code/run_worker
depends_on:
- queue
設定の追加と上書き
Compose では、元からあったサービスの定義を、ローカルのサービス定義に向けてコピーします。 設定オプションが元々のサービスとローカルのサービスの両方にて定義されていた場合は、元のサービスの値はローカルの値によって 置き換えられるか、あるいは拡張されます。
1 つの値しか持たないオプション、たとえばimage
、command
、mem_limit
のようなものは、古い値が新しい値に置き換えられます。
元からのサービス
services:
myservice:
# ...
command: python app.py
ローカル定義のサービス
services:
myservice:
# ...
command: python otherapp.py
結果
services:
myservice:
# ...
command: python otherapp.py
複数の値を持つオプション、ports
、expose
、external_links
、dns
、dns_search
、tmpfs
では、両者の設定をつなぎ合わせます。
元からのサービス
services:
myservice:
# ...
expose:
- "3000"
ローカル定義のサービス
services:
myservice:
# ...
expose:
- "4000"
- "5000"
結果
services:
myservice:
# ...
expose:
- "3000"
- "4000"
- "5000"
environment
、labels
、volumes
、devices
の場合、Compose は設定内容を「マージ」して、ローカル定義の値が優先するようにします。
元からのサービス
services:
myservice:
# ...
environment:
- FOO=original
- BAR=original
ローカル定義のサービス
services:
myservice:
# ...
environment:
- BAR=local
- BAZ=local
結果
services:
myservice:
# ...
environment:
- FOO=original
- BAR=local
- BAZ=local
volumes
やdevices
の設定内容は、コンテナーのマウントパスを使ってマージされます。
元からのサービス
services:
myservice:
# ...
volumes:
- ./original:/foo
- ./original:/bar
ローカル定義のサービス
services:
myservice:
# ...
volumes:
- ./local:/bar
- ./local:/baz
結果
services:
myservice:
# ...
volumes:
- ./original:/foo
- ./local:/bar
- ./local:/baz