CircleCI 2.0 の小ネタです。
TL; DR
リポジトリのルートに Dockerfile
がある前提です。
- CircleCI 2.0 で対象のリポジトリをプロジェクトとして有効にする
- CircleCI 2.0 上で環境変数に Docker Hub のユーザー名を
DOCKER_USER
に、パスワードをDOCKER_PASS
に登録する .circleci/config.yml
に以下のように記述する
version: 2 jobs: build: docker: - image: docker:17.07.0-ce-git steps: - checkout - setup_remote_docker - run: command: docker build -t miyajan/test-circleci-docker . - run: command: docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} - run: command: docker push miyajan/test-circleci-docker
もう少し実用的に、セマンティックバージョンのタグ(1.0.1とか)が作成されたときだけ Docker イメージの build & push を行いたい場合は以下のようになります。
version: 2 jobs: buildh: docker: - image: docker:17.07.0-ce-git steps: - checkout - setup_remote_docker - run: command: docker build -t miyajan/test-circleci-docker:${CIRCLE_TAG} . - run: command: docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} - run: command: docker push miyajan/test-circleci-docker:${CIRCLE_TAG} workflows: version: 2 build: jobs: - build: filters: branches: ignore: /.*/ tags: only: /^[0-9]+\.[0-9]+\.[0-9]+$/
説明
CircleCI で Docker イメージの build を扱うための公式ドキュメントは以下にあります。
setup_remote_docker
のステップを実行すると、Docker Engine 用のホストがリモートに立ち上がります。これ以降のステップの実行も image
で指定されたメインのコンテナの中で実行されますが、docker コマンドは
TCP 経由でリモートホストの Docker Engine を使用するようです。これは、メインのコンテナ内で docker コマンドの実行を許すと、いわゆる Docker in Docker のセキュリティ問題に直面するためこのような構成になっていると思われます。
なので、image
に使用するイメージは、docker コマンドとチェックアウトのための git コマンドがあるものが望ましいと考えられます。幸いなことに、公式の Docker イメージ に git 入りのイメージ(*-git でタグが付いてるイメージ)が存在するので、それを使うのが楽です。
特定のタグのみでビルドが実行されるようにするためには、CircleCI の Workflow の機能を使う必要があります。
上記の公式ドキュメントに書いてありますが、タグのみでビルドが実行されるようにするための条件は少し複雑です。CircleCI 2.0 はデフォルトですべてのブランチでビルドが実行され、タグでは実行されないようになっています。なので、上記の例のように、すべてのブランチを ignore して、ビルドされてほしいタグ名を正規表現で記述するという2つの設定が必要になります。
まとめ
CircleCI 2.0 で Docker イメージをビルドして Docker Hub に push する方法と、それを特定のタグでのみ実行されるようにする方法について記述しました。
もう少し実用化を考えるとイメージのキャッシュを行って高速化したいところですが、ちょっと複雑になりそうなのでまたいつか気が向いたら書くことにします。