Compose はどのように動作するか

Docker Compose では YAML 形式の設定ファイルを用います。 これを Compose ファイル と呼びます。 この設定ファイルではアプリケーションサービスを設定します。 この設定ファイルから Compose CLI を使って、サービスすべてを生成して起動します。

Compose ファイルは compose.yaml というものであり Compose 仕様 というものに基づいた規則に従って記述します。 マルチコンテナーアプリケーションの定義方法もそこで定義します。 Docker Compose は Compose 仕様 に従った公式の実装です。

アプリケーションの処理コンポーネントは services として定義されます。 サービスというものは抽象的な概念であって、一まとまりのコンテナー、イメージ、設定が複数起動されることで、プラットフォーム上に実装されます。

サービスは ネットワーク を通して互いに通信を行います。 Compose 仕様においてネットワークとはプラットフォーム機能の抽象化であり、サービス内において接続されたコンテナー間での IP ルートを確立します。

サービスは永続的なデータを保存したり共有したりするために ボリューム を利用します。 Compose 仕様ではそのような永続的データを、高度なファイルシステムマウントとして説明しています。

サービスの中には、プラットフォーム依存あるいは実行時に用いられる設定データを必要とするものがあります。 これに対して Compose 仕様では、それを扱う専用の configs という考え方を提供しています。 コンテナー内部からしてみたら、configs はさもボリュームであるかのように、つまりファイルとしてマウントされているかのように取り扱われます。 ただし configs はそうではない、プラットフォームレベルのものとして定義されます。

secret とは、機密情報を取り扱う特殊な設定データのことです。 セキュリティを考慮していない場面では、表に出してはいけない情報です。 secret はコンテナーにマウントされたファイルとして、サービスが利用可能となります。 プラットフォームのリソースとして機密情報を提供するものですが、Compose 仕様に基づいた特有の概念と定義に基づく固有情報として位置づけられます。

メモ

ボリューム、configs、secrets を使えば、トップレベルにおいて簡単に定義することができ、さらにサービスレベルにおいてプラットフォーム固有の情報を追加することもできます。

プロジェクトというものは、1 つのプラットフォーム上に実現されたアプリケーション仕様を、1 つの個別のデプロイメントとして作り出したものと言えます。 プロジェクト名は、トップレベルにおいて name 属性によって指定します。 プロジェクト名はリソースを 1 つに取りまとめるものとなります。 また同時に、他のアプリケーション、あるいは同じ Compose 仕様のアプリケーションであっても異なるパラメーターでインストールされたものとは完全に分離させるためにもあります。 特定のプラットフォーム上にリソースを生成したら、プロジェクトごとにリソース名をつけて com.docker.compose.project といったラベルを設定する必要があります。

Compose ではカスタムプロジェクト名の指定が可能であり、これを上書き設定することができます。 したがって一つの compose.yaml ファイルから、同一のインフラストラクチャー上に二つのデプロイを行うことが可能となり、その際には内容を変えることなく、単に別の名前を受け渡すだけで実現できます。

Compose ファイル

Compose ファイルのデフォルト名は compose.yaml (推奨) または compose.yml であり、ワーキングディレクトリに置きます。 Compose では旧版との後方互換のため docker-compose.yamldocker-compose.yml もサポートしています。 そういったファイルが複数存在する場合 Compose は、推奨する compose.yaml を採用します。

Compose ファイルにおいて fragmentsextensions を利用すれば、Compose ファイルを効率よく保守しやすく管理することができます。

Compose ファイルを複数 マージ して、アプリケーションモデルを定義することができます。 複数の YAML 設定ファイルの組み合わせ方は、Compose ファイルの指定順に従って YAML 設定項目が追加されたり上書きされたりします。 単純な属性やマップであれば、最終の Compose ファイルによって上書きされます。 リストであれば追加されマージされます。 相対パスは、一番初めの Compose ファイルの親フォルダーに基づいて決定されます。 マージされるファイルが補助的なものであって、それが別フォルダーに置かれていればなおさらです。 Compose ファイル内の記述要素は単純な文字列の場合もあれば、複雑なオブジェクトにより表現される場合もあります。 その場合のマージは展開された後の形で適用されます。 詳しくは 複数 Compose ファイルでの作業 を参照してください。

別の Compose ファイルを再利用したり、あるいはアプリケーションモデルの一部を個別の Compose ファイルに分割したい場合は include を利用します。 Compose アプリケーションが他チームの管理するアプリケーションに依存していたり、他チームとの共有が必要なものであったりする場合には、この手法が活用できます。

CLI

Docker CLI は docker compose およびそのサブコマンドを通じて、Docker Compose アプリケーションとの対話を行うために用います。 Docker Desktop を利用している場合、Docker Compose CLI はデフォルトで含まれています。

CLI を使えば compose.yaml ファイルにマルチコンテナーアプリケーションが定義されていても、そのライフサイクルを管理できます。 CLI からはアプリケーションの起動、停止、設定を簡単に行うことができます。

主要なコマンド

compose.yaml ファイル内に定義されたサービスをすべて起動します。

$ docker compose up

実行中のサービスを停止して削除します。

$ docker compose down

実行中のコンテナーの出力を確認したりデバッグをしたりする場合は、以下のコマンドを実行してログを参照します。

$ docker compose logs

全サービスとそのステータスを一覧表示します。

$ docker compose ps

Compose CLI コマンドの全一覧は リファレンスドキュメント を参照してください。

イラストで示す例

以下の例は、上述した Compose の概要をイラストを使って説明するものです。 なお本例は模範的なものではありません。

アプリケーションが、フロントエンドのウェブアプリケーションとバックエンドのサービスに分かれているとします。

フロントエンドは実行時に HTTP の設定ファイルによって定まります。 これはインフラストラクチャーが管理するものです。 HTTP 設定ファイルでは外部ドメイン名を設定し、プラットフォームにおけるセキュアな機密情報ストアから定まる HTTPS サーバー証明書を使用しています。

バックエンドにおけるデータは、永続的なボリュームに保存されます。

2 つのサービスは独立した back-tier ネットワーク上において互いに通信を行います。 またフロントエンドは front-tier ネットワークにも接続して、外部からの接続向けにポート 443 番を利用します。

Compose アプリケーションの例

このアプリケーション例では、以下の部分から構成されます。

  • Docker イメージに定義された 2 つのサービス、webappdatabase
  • フロントエンドにて用いられる 1 つの機密情報 (HTTPS 証明書)
  • フロントエンドにて用いられる 1 つの設定 (HTTP)
  • バックエンドに結びつけられる 1 つの永続的ボリューム
  • 2 つのネットワーク
services:
  frontend:
    image: example/webapp
    ports:
      - "443:8043"
    networks:
      - front-tier
      - back-tier
    configs:
      - httpd-config
    secrets:
      - server-certificate

  backend:
    image: example/database
    volumes:
      - db-data:/etc/data
    networks:
      - back-tier

volumes:
  db-data:
    driver: flocker
    driver_opts:
      size: "10GiB"

configs:
  httpd-config:
    external: true

secrets:
  server-certificate:
    external: true

networks:
  # The presence of these objects is sufficient to define them
  front-tier: {}
  back-tier: {}

docker compose up コマンドを実行すると frontendbackend というサービスが起動します。 また必要となるネットワークとボリュームを生成し、設定ファイルと機密情報をフロントエンドサービスに提供します。

docker compose ps はサービスの状態を確認します。 実行中のサービスは何か、どのような状態にあるか、利用ポートは何かがわかります。

$ docker compose ps

NAME                IMAGE                COMMAND                  SERVICE             CREATED             STATUS              PORTS
example-frontend-1  example/webapp       "nginx -g 'daemon of…"   frontend            2 minutes ago       Up 2 minutes        0.0.0.0:443->8043/tcp
example-backend-1   example/database     "docker-entrypoint.s…"   backend             2 minutes ago       Up 2 minutes

次は何?