この記事では、docker-composeを使用して大規模プロジェクトの起動、テスト、構成を自動化した経験を共有します。 いくつかの簡単な変更により、チームの効率が向上し、日常的なタスクではなく重要なタスクに時間をかけることができます。
2017年のDocker
Dockercon 2016カンファレンスで、DockerのCEOは、Dockerで実行されるアプリケーションの数が過去2年間で3100%増加したと述べました。 Dockerでは、世界中で46万を超えるアプリケーションが起動されています。 これは信じられないほどです!
まだDockerを使用していない場合は、世界中のDockerの使用に関する優れた記事を読むことをお勧めします。 Dockerはアプリケーションの作成方法を完全に変更し、開発者とDevOpsチームにとって不可欠な部分になりました。 この記事では、既にDockerに精通しているため、引き続きDockerを使用するもう1つの理由を説明したいと考えています。
何が悪いの?
キャリアを始めて以来、Webアプリケーションを開発していたとき、作業環境でアプリケーションを起動することは常に困難な作業でした。 データベースのインストールから、アプリケーションを構成して起動するまで、多くの追加作業が必要でした。 開発者 愛する 彼らはドキュメントを書きたくないので、プロジェクトを開始する手順は通常、チームメンバーの頭の中に隠されています。 その結果、プロジェクトの立ち上げは、特に新しい人にとっては、骨の折れる作業になります。
多くのプロジェクトは最初は単純ですが、時間が経つにつれて大きくなります。 これにより、データベース、キューなどの外部依存関係が増加します。 マイクロサービスの人気の高まりにより、多くのプロジェクトはモノリシックではなくなり、いくつかの小さな部分に分割されています。 そのような変更は、チーム全体の注意を必要とします。そのような変更の後、プロジェクトを別の方法で立ち上げる必要があるからです。 通常、ルートの変更に関与する開発者は、作業環境でプロジェクトが再び開始されるように、実行する必要がある手順の説明を記載したレターを作成するか、Wikiページを作成します。 通常は動作しますが、常にではありません:)別の大陸の開発者がプロジェクトに多くの変更を加え、長い手紙を書いて就寝するという状況に私たちのチームが陥ると、 あなたは次に何が起こったか知っていると思います。 そうです、彼はいくつかの重要な点に言及するのを忘れていました。 その結果、翌日、チームの一部はプロジェクトを開始できず、その日は失われました。
エンジニアとして、私は周りのすべてを自動化するのが好きです。 立ち上げ、テスト、展開は常にワンステップである必要があると思います。 この場合、チームは製品の開発と改善という重要なタスクに集中できます。 10年前は困難でしたが、今では自動化がはるかに容易になり、すべてのチームがこれに時間を割く必要があります。 早ければ早いほど良い。
docker-composeのクイックスタート
Docker-composeは、単一のコマンドで複数のコンテナーを構成および実行できるシンプルなツールです。 docker-composeをさらに深く掘り下げる前に、プロジェクト構造について詳しく調べる必要があります。 「monorepo」を使用します。 各サービスのコード(フロントエンド、API、ワーカーなど)はそのディレクトリにあり、Dockerfileがあります。 プロジェクト構造の例はここにあります 。
docker-composeの構成全体は、通常プロジェクトのルートにあるdocker-compose.yml
に記述されていdocker-compose.yml
。 まずは、MongoDBデータベースと連携する単純なNode.JSアプリケーションを自動化することから始めましょう。 設定ファイルは次のようになります。
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を使用した場合、docker-composeの構成ファイルは多少明確になりますが、いくつかの詳細に注意する必要があります。
-
context: ./web
これは、リポジトリ内のcontext: ./web
サービスファイルへのパスを示します。 -
dockerfile: Dockerfile.dev
作業環境用に別個のDockerfile.devを使用します。 「実稼働」環境では、コードをDockerイメージにコピーし、実稼働環境では「ボリューム」としてコードを追加します。 「ボリューム」を使用する場合、コードの変更後に毎回docker-composeを再起動する必要はありません。 -
volumes: - "./web/src:/web/src"
-これは、コードがDockerで「ボリューム」として追加される方法です。 - Docker-composeはコンテナを自動的にバインドします。 これにより、名前でサービスにアクセスできます。 たとえば、
web
サービスからデータベースMongoDBに接続できます:mongodb://mongo:27017
常に--build
使用します
デフォルトでは、 docker-compose up
は、コンテナが既にホスト上にある場合、コンテナを再構築しません。 dockerでこれを行うには、 --build
引数を使用します。 これは通常、サードパーティのプロジェクトの依存関係が変更された場合、またはdockerfileが変更された場合に必要です。 私たちのチームでは、常にdocker-compose up --build
使用します。 Dockerはレイヤーをキャッシュでき、何も変更されていない場合はコンテナを再構築しません。 あらゆる場所で--build
を使用すると、アプリケーションの起動時に数秒かかる場合があります。 しかし、同時に、古い依存関係を持つアプリケーションの新しいバージョンを起動するという魔法の問題に遭遇することは決してありません。
ヒント:プロジェクトの起動コマンドを単純なbashスクリプトでラップできます。
#!/bin/sh docker-compose up --build "$@"
これにより、アプリケーション全体を起動するための引数またはアプローチを変更する機会が与えられます。 チームの場合、常に./bin/start.sh
ように./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に設定するだけです。
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 up
、docker-composeは現在のディレクトリでdocker-compose.yml
設定ファイルを探します。 場合によっては(これについてすぐに話しましょう)、そのような構成ファイルをいくつか作成する必要があります。 これを行うには、 --file
引数を使用する--file
です。
docker-compose --file docker-compose.local-tests.yml up
では、なぜいくつかの構成ファイルが必要なのでしょうか? 最初の使用例は、大きなプロジェクトをいくつかの小さなプロジェクトに分割することです。 興味深いことに、複数の個別のdocker-composeを実行しても、サービスは、docker-composeから名前で相互に通信できます。 たとえば、インフラストラクチャコンテナ(データベース、キューなど)とアプリケーションコンテナを個別のdocker-composeファイルに分離できます。
テストを実行する
テストには、ユニット、統合、UIテスト、コード構文チェックなどのさまざまなタイプが含まれます。 各サービスには、独自のテストセットがあります。 統合およびUIテストを機能させるには、 api
とweb frontend
が必要です。
最初は、docker-composeが起動するたびにテストを実行する必要があるように思われました。 しかし、すぐにそれが必ずしも便利ではなく、時間がかかりすぎることに気付きました。 場合によっては、実行するテストをもう少し制御したいこともありました。 これを行うには、別個の構成docker-composeファイルを使用します。
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によってコンパイルされたイメージを使用します。 たとえば、特定のサービスに対してのみテストを実行することもできます。
docker-compose --file docker-compose.local-tests.yml up api-tests
このコマンドは、 api
サービスのテストのみを実行します。
コンテナのプレフィックス
デフォルトでは、docker-composeを使用して実行されるすべてのコンテナは、現在のディレクトリの名前をプレフィックスとして使用します。 このディレクトリの名前は、開発者の作業環境によって異なる場合があります。 このプレフィックス( app_
)は、メインのdocker-composeファイルからコンテナを参照するときに使用されます。 このプレフィックスを修正するには、 .env
ファイルを作成する必要があります docker-compose構成ファイルの横 docker-composeの起動元ディレクトリ内:
COMPOSE_PROJECT_NAME=app
したがって、プレフィックスはすべての作業環境で同じになります。
おわりに
Docker-composeは、プロジェクトの起動を自動化する非常に便利で柔軟な方法です。
新しい開発者がチームに追加されると、彼らに小さなタスクを与えます。彼らは最初の営業日の終わりまでに完了する必要があります。 私たちのチームに参加した全員がこれに対処し、地球上で最も幸せな人でした。 最初の数分から、新しい開発者はプロジェクトの開始に時間を無駄にせずに重要なタスクに集中できます。 プロジェクトを開始するためのドキュメントは、3つのポイントで構成されています。
- DockerとDocker-composeをインストールする
- リポジトリのクローン
- ターミナル
./bin/start.sh
実行します
この記事を理解しやすくするために、Githubにサンプルプロジェクトがあります。 あなたの経験を共有し、 質問をしてください。
この記事が有用であり、プロジェクトの改善に役立つことを願っています:)