「インクルード」でDocker作成モジュール性を改善する

このブログ投稿では、Compose v2.20.0 および Docker Desktop 4.22 リリースで利用できる機能について説明します。

コマンドラインでは docker 、コンテナを微調整するための多くのフラグがサポートされており、環境をレプリケートするときにそれらすべてを覚えることは困難です。 アプリケーションが単一のコンテナーではなく、さまざまな依存関係を持つ多数のコンテナーの組み合わせである場合、これを行うことはさらに困難です。 これに基づいて、 Docker Compose は、ユーザーがコマンドラインに直接触発された単純な構文を使用して、コンテナベースのアプリケーションのすべてのインフラストラクチャの詳細を単一のYAMLファイルに宣言できるため、 docker run… すぐに人気のあるツールになりました。

それでも、数十、場合によっては数百のコンテナーを使用し、所有権が複数のチームに分散されている大規模なアプリケーションでは、問題が解決しません。 モノレポを使用する場合、多くの場合、チームはアプリケーションのサブセットを実行するための独自の "ローカル" Docker Compose ファイルを持っていますが、その後、独自のサブセットを実行するための予想される方法を定義する参照作成ファイルを提供するために他のチームに依存する必要があります。

この問題は新しいものではなく、Docker Composeが新しいプロジェクトであり、問題番号が3桁しかなかった 2014年に議論 されました。 このニーズに対応するために、この号が10周年を迎える前でも、「作成ファイルを作成する」機能を導入しました。

この記事では、Docker Compose 2.20 で導入された 新しい include 属性によって、Compose ファイルのモジュール化と再利用性がどのように向上するかについて説明します。

黒いウィンドウに白いテキストに「include」を重ねた紫色の背景を示すグラフィック。

作成ファイルを拡張する

Docker Compose では、この extends メカニズムを使用して既存の作成ファイルを再利用できます。 この特別な構成属性を使用すると、別の Compose ファイルを参照し、独自のアプリケーションで使用するサービスを選択し、必要に応じて属性をオーバーライドできます。

services:
  database:
    extends:
        file: ../commons/compose.yaml
        service: db

これは、共有するサービスが1つだけで、その内部の詳細を知っているため、構成を微調整する方法を知っている限り、優れたソリューションです。 しかし、他の人の構成を「ブラックボックス」として再利用し、それ自身の依存関係について知らない場合は、受け入れられる解決策ではありません。

作成ファイルのマージ

別のオプションは、一連のComposeファイルをマージすることです。 Docker Compose は一連のファイルを受け入れ、サービス定義をマージしてオーバーライドし、最終的に複合 Compose アプリケーション モデルを作成します。

このアプローチは何年にもわたって利用されてきましたが、特定の課題が伴います。 つまり、Docker Compose は、サービス イメージのビルド コンテキスト、環境変数を定義するファイルの場所、バインド マウントされたボリュームで使用されるローカル ディレクトリへのパスなど、アプリケーション モデルに含まれる多くのリソースの相対パスをサポートします。

このような制約があると、チームまたはコンポーネントごとに専用のフォルダーを用意するのが自然な選択であるため、モノリポジトリでのコード編成が困難になる可能性がありますが、その場合、ファイルの作成相対パスは関係ありません。

「データベース」チームの役割を果たし、担当するサービスのComposeファイルを定義しましょう。 次に、Dockerfile から独自のイメージをビルドし、参照環境をファイルとして env 設定します。

services:
  database:
    builld: . 
    env-file:
      - ./db.env

それでは、別のチームに切り替えて、データベースへのアクセスを必要とするWebアプリケーションを構築しましょう。

services:
  webapp:
    depends_on:
    - database 

それらを結合しようとするまでは、ディレクトリから webapp 以下を実行します: docker compose -f compose.yaml -f ../database/compose.yaml

そうすることで、2番目のComposeファイルによって設定された相対パスは、作成者によって設計されたとおりに解決されるのではなく、ローカルの作業ディレクトリから解決されます。 したがって、結果のアプリケーションは期待どおりに動作しません。

他のチームのコンテンツを再利用する

旗は include まさにこの必要性のために導入されました。 名前が示すように、この新しい最上位の属性は、完全なコピー/貼り付けを行ったのと同じように、独自のアプリケーションモデルに含まれるComposeファイル全体を取得します。 唯一の違いは、相対パス参照を管理するため、インクルードされたComposeファイルが作成者の期待どおりに解析され、元の場所から実行されることです。 この機能により、正確な詳細を知ることなく、別のチームのコンテンツを再利用することがはるかに簡単になります。

include:
../database/compose.yaml

services:
  webapp:
    depends_on:
     - database 

この例では、インフラストラクチャ チームがサービスを管理するための database Compose ファイルを準備しており、レプリカ、データを検査するための Web UI、分離されたネットワーク、データの永続性に関するボリュームなどが含まれています。

このサービスに依存するアプリケーションは、これらのインフラストラクチャの詳細を知る必要はなく、信頼できる構成要素として Compose ファイルを使用します。 したがって、インフラストラクチャ チームは、独自のデータベース コンポーネントをリファクタリングして、依存チームに影響を与えることなく追加のサービスを導入できます。

このアプローチには、別の Compose ファイルへの依存関係が明示的になり、ユーザーが実行する各 Compose コマンドに追加のフラグを含める必要がないという利点もあります。 代わりに、アプリケーションアーキテクチャに関する追加の知識がなくても、最愛 docker compose up のコマンドに頼ることができます。

結論

マイクロサービスとモノレポでは、アプリケーションが数十のサービスに分割され、複雑さがコードからインフラストラクチャと構成ファイルに移動するのが一般的になります。 Docker Composeは単純なアプリケーションに適していますが、そのようなコンテキストで使用するのは困難です。 少なくとも今まではそうでした。

Docker Compose のサポートにより include 、このような複雑なアプリケーションをサブ作成ファイルに簡単にモジュール化できます。 この機能により、アプリケーションの構成をより簡単かつ明示的にすることができます。 また、コードを担当するエンジニアリング チームを構成ファイルの構成に反映させるのにも役立ちます。 各チームが他のチームの作業に依存する方法を構成に反映できるため、ファイル編成には compose.yaml 自然なアプローチがあります。

この新機能 include の詳細については、 専用の Compose 仕様ページ を参照し、Docker Compose を v2.20 以降にアップグレードして試してみてください。

さらに詳しく