LoginSignup
59
24

More than 5 years have passed since last update.

CircleCI 2.0 では Docker ビルドキャッシュが効く

Last updated at Posted at 2017-04-26

2通りのやり方がある。pull/cache-from を使う方法と、save/load を使う方法。
手元のプロジェクトだと前者の方がだいぶ速い。

1. pull/cache-from を使う方法

version: 2
jobs:
  build:
    machine: true
    environment:
      - DOCKER_IMAGE_REPO: your-private-repository
    working_directory: ~/your-repo
    steps:
      - checkout
      - # ...必要に応じて ecr login など
      - run: docker pull $DOCKER_IMAGE_REPO:latest
      - run: docker build -t circleci --cache-from $DOCKER_IMAGE_REPO:latest .
      - run: docker tag circleci $DOCKER_IMAGE_REPO:latest
      - run: docker push $DOCKER_IMAGE_REPO:latest

既存の latest イメージを pull して、ビルド時に --cache-from として指定する。
このオプションは Docker 1.13 で追加された もので、以前は pull したイメージをキャッシュとして利用する手段が存在しなかった。
CircleCI 1.0 では Docker 1.10 の独自拡張版を利用していたが、CircleCI 2.0 で Docker のバージョンが新しくなったため可能となった。

jobtalk_cf-recommend__102_-_CircleCI.png

イメージサイズは 800 MB 程度だが、pull に 4 分かかる。0 からビルドするよりは速いので許容できる。

2. save/load を使う方法

.circleci/config.yml にこんな内容を書けば良い。

version: 2
jobs:
  build:
    machine: true
    working_directory: ~/my-repo
    steps:
      - checkout
      # 1. キャッシュリストア
      - restore_cache:
          keys:
            - my-docker-cache-{{ .Branch }}
            - my-docker-cache
      # 2. キャッシュイメージ読み込み
      - run: if test -d ~/cache; then docker load -i ~/cache/image.tar; fi
      # 3. ビルド
      - run: docker build -t my-image .
      # 4. イメージ書き出し
      - run: mkdir -p ~/cache && docker save -o ~/cache/image.tar my-image $(docker history -q my-image | tail -n +2 | grep -v \<missing\> | tr '\n' ' ')
      # 5. キャッシュ保存
      - save_cache:
          key: my-docker-cache-{{ .Branch }}-{{ checksum "~/cache/image.tar" }}
          paths:
            - ~/cache

ビルド終了時に docker save でイメージの 全レイヤをまとめて tar に保存し、CircleCI のキャッシュ機構を使って tar を保存する。
ビルド開始時に前回のキャッシュ (tar) をリストアし、docker load でロードしてやれば良い。

Docker 1.10 にはイメージのキャッシュをファイルからロードする手段が存在しない。そのため CircleCI 1.0 ではビルド間でキャッシュを持ち越せなかった。(参考: CircleCI で Docker ビルドキャッシュができない理由)

また、Docker ビルド環境にキャッシュファイルを渡すため、 executor type は machine でなければいけない。

jobtalk_cf-recommend__87_-_CircleCI.png

Restore(CircleCI Cache), docker load, docker save, Save(CircleCI Cache) それぞれで地味に時間がかかる。

備考

docker save/load を明示的に書かずにキャッシュ効かせる方法も用意されているが、2017/04 現在特別に申請された一部のリポジトリのみ有効であり、将来的には有料オプションになるかもしれないらしい。 (https://circleci.com/docs/2.0/docker-layer-caching/)

参考

59
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
24