docker-composeを使用した完全に自動化された開発環境

Dockercon 2016で発表したDockerのCEO、Ben Golubによると、Dockerコンテナで実行されるアプリケーションの数は過去2年間で3100%増加しています。 Dockerは、世界中で460,000個のアプリケーションを提供しています。 これは信じられないほどです!


Dockerの使用をまだ開始していない場合は、この印象的な導入ドキュメントをお読みください。 Dockerは、アプリケーション構築のアプローチを変更し、開発者およびDevOpsプロフェッショナルにとって非常に重要なツールになりました。 この記事は、すでにDockerを使用している人を対象としており、これを続ける必要がある別の理由を発見することを目的としています。


大規模なプロジェクトでdocker-composeを使用した経験を共有したいと思います。 このツールを使用して、開発、テスト、構成に関連するタスクを自動化することで、いくつかの簡単な手順で、チームをより効率的にし、製品開発に直接集中することができました。


問題


私のキャリアの初め、私がまだc#とasp.netで若い開発者だったとき、開発環境を展開するのは簡単な作業ではありませんでした。 アプリケーションが機能するために必要なデータベースとツールをインストールする必要がありました。 この場合、構成ファイルは、ローカルマシンの設定に対応するように変更する必要がありました。 ポート、ローカルディレクトリへのパス、更新などを登録する必要がありました。 通常、これらの手順は十分に文書化されていないため、開発環境の起動には膨大な時間がかかりました。


開発の初期段階にある多くの製品は難しくありませんが、新しい機能が実装されると、それらに対処することがより難しくなります。 追加のデータベースやメッセージキューなど、新しいツールとサブシステムを追加します。 マイクロサービスの人気の高まりにより、大規模アプリケーションのモノリシックモンスターは、ますます多くの部分に分割されています。 このような変更には、通常、プロジェクトに取り組んでいるチーム全体の参加が必要です。 ローカル環境を壊すような変更を行う開発者は、通常、構成に必要な手順のリストを含む長い手紙を書きます。 海外で働くある専門家が製品の構造に重大な変更を加え、現地環境の作業能力を回復するための指示を書いた手紙を書き、眠りについたときのことを思い出します。 あなたは次に何が起こったのか推測したと思います。 そうです:彼はいくつかの重要な点に言及するのを忘れていました。 その結果、ほとんどのチームは、ローカルの作業環境で動作するように更新されたコードを取得しようとして、翌営業日を失いました。


開発者はドキュメントを書くのが非常に(好きではありません)、プロジェクトを開始するためのいくつかの手順は、多くの場合、自分の頭の中だけに保存​​されます。 その結果、特に初心者にとって、ゼロから作業環境をセットアップすることは簡単なことではありません。


他のエンジニアと同様に、私は周りのすべてを自動化するよう努めています。 アプリケーションの起動、テスト、および展開は1つのステップで行う必要があると確信しています。 これにより、チームは製品の開発と改善という非常に重要なことに集中できます。 10年前、これらのタスクの自動化は現在よりもはるかに困難でした。 今では誰もがそれを行うことができますし、すべきです。また、開始するのが早ければ早いほど良いです。


docker-composeのクイックスタート


Docker-composeは、1つのコマンドで複数のdockerコンテナーを実行できるシンプルなツールです。 詳細に入る前に、プロジェクトの構造について話さなければなりません。 monorepoを使用し、各サービス(Webアプリケーション、API、バックグラウンドハンドラー)のコードベースはそのルートディレクトリに格納されます。 各サービスには、依存関係を記述するDockerファイルがあります。 このような構造の例は、 デモプロジェクトで見ることができます。


MongoDBとNode.JSの小さなサービスに依存する単純なアプリケーションを自動化することから始めましょう。 docker-composeの設定はdocker-compose.ymlにありdocker-compose.yml 。このdocker-compose.ymlは通常、プロジェクトのルートディレクトリにあります。


 version: '2' services: web: build: context: ./web dockerfile: Dockerfile.dev volumes: - "./web/src:/web/src" ports: - "8080:8080" mongo: command: mongod image: mongo:3.2.0 ports: - "27100:27017" # map port to none standard port, to avoid conflicts with locally installed mongodb. volumes: - /var/run/docker.sock:/var/run/docker.sock 

プロジェクトを開始するには、1つのコマンドのみを実行する必要があります。


 $ docker-compose up 

最初の起動時に、必要なすべてのコンテナが作成またはロードされます。 一見したところ、特にDockerを使用していた場合は特に複雑ではありませんが、それでも詳細を説明しましょう。


  1. context: ./webこれは、monorepo内のサービスのソースコードへのパスを指定します。
  2. dockerfile: Dockerfile.dev開発環境では、別個のDockerfile.devを使用します。 本番環境では、ソースコードはコンテナに直接コピーされ、開発のためにボリュームとして接続されます。 したがって、コードが変更されるたびにコンテナを再作成する必要はありません。
  3. volumes: - "./web/src:/web/src" -この方法で、コードのあるディレクトリがボリュームとしてvolumes: - "./web/src:/web/src"追加されます。
  4. Docker-composeはコンテナーを自動的に相互に関連付けます。たとえば、Webサービスはmongodbに名前でアクセスできます: mongodb://mongo:27017

常に--build引数を使用します


デフォルトでは、コンテナがすでにホスト上にある場合、 docker-compose upはそれらを再作成しません。 この操作を強制するには、 --build引数を使用します。 これは、サードパーティの依存関係またはDockerファイル自体が変更される場合に必要です。 常にdocker-compose up --build実行することをルールにdocker-compose up --build 。 Dockerはコンテナレイヤーを完全にキャッシュし、何も変更がなければコンテナレイヤーを再作成しません。 --build継続的に使用すると、ロードが数秒間遅くなる可能性がありますが、古いサードパーティの依存関係で動作するアプリケーションに関連する予期しない問題を防ぎます。


ヒント:プロジェクトの開始を簡単なスクリプトで抽象化できます:


 #!/bin/sh docker-compose up --build "$@" 

この手法により、必要に応じて、起動時に使用されるオプションとツールを変更できます。 または、単に./bin/start.sh実行できます。


部分打ち上げ


docker-compose.ymlの例では、一部のサービスは他のサービスに依存しています。


  api: build: context: ./api dockerfile: Dockerfile.dev volumes: - "./api/src:/app/src" ports: - "8081:8081" depends_on: - mongo 

このフラグメントでは、 apiサービスにはデータベースが必要です。 docker-composeを使用する場合、サービスの名前( docker-compose up apiのみ)を実行するように指定できます。 このコマンドは、MongoDBを起動し、その後APIサービスを起動します。 大規模なプロジェクトでは、このような機能が役立ちます。


この機能は、異なる開発者がシステムの異なる部分を必要とする場合に役立ちます。 たとえば、ランディングページで作業するフロントエンドのスペシャリストはプロジェクト全体を必要とせず、ランディングページ自体で十分です。


不要なログイン> / dev / null


一部のプログラムでは、ログが多すぎます。 ほとんどの場合、この情報は役に立たず、気を散らすだけです。 デモリポジトリでは、ログドライバーをnoneに設定してMongoDBログをオフにしました。


  mongo: command: mongod image: mongo:3.2.0 ports: - "27100:27017" volumes: - /var/run/docker.sock:/var/run/docker.sock logging: driver: none 

複数のdocker-composeファイル


docker-compose up実行すると、デフォルトで現在のディレクトリでdocker-compose.ymlを検索しdocker-compose.yml


場合によっては(これについては後で説明します)、いくつかのdocker-compose.ymlが必要になる場合がありdocker-compose.yml 。 別の構成ファイルを含めるには、 --file引数を使用できます。


 docker-compose --file docker-compose.local-tests.yml up 

では、なぜ複数の構成ファイルが必要なのでしょうか? まず、複合プロジェクトをいくつかのサブプロジェクトに分割します。 さまざまな構成ファイルのサービスを引き続き接続できることを嬉しく思います。 たとえば、インフラストラクチャ関連のコンテナ(データベース、キューなど)を1つのdocker-composeファイルに配置し、アプリケーション関連のコンテナを別のdocker-composeファイルに配置できます。


テスト中


ユニット、統合、UI、リンティングなどのさまざまなタイプのテストを使用します。 サービスごとに個別のテストセットが開発されています。 たとえば、統合およびUIテストを実行するには、APIおよびWebサービスが必要です。


最初は、メインの構成ファイルが実行されるたびにテストを実行する方が良いと考えましたが、すぐに時間がかかることがわかりました。 場合によっては、特定のテストを実行できる必要がありました。 このために、別の構成ファイルが作成されました。


 version: '2' services: api-tests: image: app_api command: npm run test volumes: - "./api/src:/app/src" web-tests: image: app_web command: npm run test volumes: - "./web/src:/app/src" 

テスト構成ファイルは、メインのdocker-composeファイルに依存しています。 統合テストはapi開発バージョンに接続し、UIテストはweb frontend接続します。 テスト構成ファイルは、メインのdocker-composeファイルで作成されたコンテナーのみを実行します。 1つのサービスのみに対してテストを実行する場合、部分的な実行を使用できます。


 docker-compose --file docker-compose.local-tests.yml up api-tests 

このコマンドは、 apiテストのみを実行します。


コンテナ名のプレフィックス


デフォルトでは、docker-composeを使用して起動されたすべてのコンテナには、親ディレクトリの名前の形式でプレフィックスが割り当てられます。 さまざまな開発環境のディレクトリの名前は変更できます。 このため、前に説明したDocker構成テストファイルが機能しなくなる場合があります。 メインのapp_ -composeファイルのコンテナにはプレフィックス( app_ )を使用します。 さまざまな環境で一貫した構成作業を行うために、docker-composeを実行するディレクトリに特別な.envファイルを作成しました。


 COMPOSE_PROJECT_NAME=app 

したがって、親ディレクトリの名前に関係なく、すべての環境でコンテナに同じプレフィックスが割り当てられていることを確認できます。


おわりに


Docker-composeは、プロジェクトの作業に使用するソフトウェアを実行するための便利で柔軟なツールです。


新しい開発者が来たとき、通常は最初の日に開発者に本番環境で簡単な機能を導入したり、バグを修正したりします。 スタートガイドは次のようになります。


1) DockerおよびDocker-composeをインストールします
2)GitHubリポジトリをコピーし、
3)ターミナルでコマンド./bin/start.shを実行します。


この記事で紹介した概念をよりよく理解するには、GitHubに投稿されたデモプロジェクトをご覧になることをお勧めします。 あなたの経験を共有し、 質問をしてください。


この記事がお役に立てば幸いです。受け取った情報がプロジェクトの改善に役立つことを願っています:)


オリジナル: docker-composeを使用した完全に自動化された開発環境



Source: https://habr.com/ru/post/J325568/


All Articles