batect

build and testing environments as code tool: Dockerised build and testing environments made easy

charleskorn/batect

Problems

  • プロジェクトに参加する際の環境構築は面倒で間違えやすい
  • CIサーバーや複数の開発者間で環境が統一されていないと再現性に問題が出てくる

Idea

  • Dockerによる一貫性と可搬性の担保
  • Yamlを用いて、環境定義を開発リポジトリ内で管理

Sales pitch

  • 自身のコンピューター/同僚のコンピューター/CIサーバーのどこであっても高速で一貫性があり反復可能である
  • ビルドやテストといった一般的なタスクを構造化された文書としてチーム内で共有可能
  • ITやE2Eテストを実行するための外部依存も定義可能
  • 新しいプロジェクトメンバーでも数分で環境構築
  • Linux、OS X、Windowsをサポート
  • 任意の言語やフレームワーク、既存のCIシステムで動作可能
  • 既存のDockerイメージを活用してすぐに始められる

Requirements

  • Docker 17.06 or newer
  • Java 8 or newer (although this requirement will be removed before v1.0)
  • On Linux and OS X: Bash and curl
  • On Windows: Windows 10

Install

releaseページにあるbashスクリプトをダウンロードして、実行権限を付与

batectファイルはテキストファイルなのでリポジトリにポン置きすればbatectのバージョンも統一可能

https://github.com/charleskorn/batect/releases

Getting Started

  1. batect.yml ファイルを作成
containers:
  build-env:
    image: openjdk:8u141-jdk
    volumes:
      - local: .
        container: /code
        options: cached
      - local: .gradle-cache
        container: /home/container-user/.gradle
        options: cached
    working_directory: /code
    environment:
      GRADLE_OPTS: -Dorg.gradle.daemon=false
    run_as_current_user:
      enabled: true
      home_directory: /home/container-user

tasks:
  build:
    description: Build the application.
    run:
      container: build-env
      command: ./gradlew assembleDist

  unitTest:
    description: Run the unit tests.
    run:
      container: build-env
      command: ./gradlew test
  1. batect build などtaskを指定することで実行される

Use original Dockerfile

./batect/database/Dockerfile がビルドされて利用される

batect.yml

containers:

  ...

  database:
    build_directory: .batect/database
    environment:
      - POSTGRES_USER=international-transfers-service-user
      - POSTGRES_PASSWORD=TheSuperSecretPassword
      - POSTGRES_DB=international-transfers-service

Run task with dependency containeres

dependenciesに指定したコンテナを依存コンテナとして立ち上げてくれる

batect.yml

tasks:

  ...

  integrationTest:
    description: Run the integration tests.
    run:
      container: build-env
      command: ./gradlew integrationTest
    dependencies:
      - database

Compare to other tools

vagrant

  • 仮想マシンは重たいのでCIサーバーなどで実行する際に問題が出る
  • 仮想マシンはライフサイクルが長いので構成の変更に追従しそこねるケースが出てくる

docker-compose

  • タスクという概念がないので、自動化しようと思うと高レベルのスクリプトを用意しないといけなくなってしまう
  • 起動時のパフォーマンスに懸念がある

CI local runner

GitLab CI や CircleCI などに搭載されているローカルCLI機能。

ローカルCLIは、開発者が日常の開発ツールではなく、ビルド構成の変更をテストできるようにするためのものであり、 batectはCIでも同様に機能する優れた日々の開発ツールとして設計されている。

  • よりシンプルで使いやすいCLI、より明確で簡潔な出力、より明確なエラーメッセージ
  • 全てのDockerイメージがレジストリに登録されている必要がない(依存としてローカルのDockerfileを利用可能)
    • イメージの一時的な修正(debugコマンドの追加)などが用意
    • Dockerfileの変更をコードの変更とともにバージョン管理できる
  • ビルドでは使用されないが開発者が使用するタスクを定義するのに向いていない
  • ローカル作業コピーをビルドコンテナーに簡単にマウントすることをサポートしていないので、コードの変更を検出することに依存するタスクには使用できない
  • 追加の引数をタスクに渡すことをサポートしていないため、デバッガの有効化やログレベルを変更するような開発に役立つオプションを利用できない
  • 依存コンテナに対して、その完全な起動を待つような機能(helth_check)やウォームアップなどを行うことができない