LoginSignup
28
12

More than 5 years have passed since last update.

CircleCI 2.0のworkflowsを利用していい感じにdocker-composeをcacheする

Last updated at Posted at 2017-07-30

前置き

CircleCIのworkflowで上手いことdocker-composeの重い処理をなんとかするのをやってみた。

今回はdocker-composeのbuild処理が重くてtest並列化するとそこがボトルネックになるような場合を想定している。
build自体が重くない場合や並列化が不要な場合は、むしろcache生成・呼び出しで遅くなるパターンもある。

Enabling Docker Layer Cachingなど公式のdockerキャッシュもあるが、machineモードでないとdocker-composeがフルに利用できない(volumesが利用できない)のでsave_cache / restore_cacheを使うやり方を色々ひねった。

手始めにdockerをcacheしてみる

docker-composeに飛びつく前に、docker単体のpullとtestをworkflowで分離してみる。

dockerのcache利用自体は下記で語られているのをほぼ利用する。

docker imagesをまるっとsaveするやり方は下記を参考にした

今回はなんでもよかったが、nodeのimageを利用した。

circle.yml
version: 2
jobs:
  generate_cache:
    machine: true
    steps:
      - checkout
      - run: docker pull node:8.2.1-onbuild
      - run: # cacheのために吐き出し
          command: |
            mkdir -p ~/caches
            docker save $(docker images -q) -o ~/caches/images.tar
      - save_cache:
          key: docker-{{ .Revision }}
          paths: ~/caches/images.tar
  test:
    machine: true
    steps:
      - checkout
      - restore_cache:
          key: docker-{{ .Revision }}
          paths: ~/caches/images.tar
      - run:
          command: |
            set +o pipefail
            docker load -i ~/caches/images.tar | true
      # - run: docker images # imageが持ってこれてることを確認したければこんなコマンドを差し込む
      - run:
          name: pull # キャッシュ利用しているため、早い(0秒)
          command: docker pull node:8.2.1-onbuild
workflows:
  version: 2
  build:
    jobs:
      - generate_cache
      - test:
          requires:
            - generate_cache

cacheのキーはリビジョンを利用した。test側でのbuildが0秒になる。

docker-composeをcacheする。

やり方はほぼ一緒。docker-compose pulldocker-compose buildをしてsaveする。

circle.yml
version: 2
jobs:
  generate_cache:
    machine: true
    steps:
      - checkout
      - restore_cache:
          key: docker-{{ .Branch }}-{{ checksum "docker-compose.yml" }}-{{ checksum "Dockerfile" }}
          paths: ~/caches/images.tar
      - run:
          command: |
            set +o pipefail
            docker load -i ~/caches/images.tar | true
      - run: pip install docker-compose
      - run: docker-compose pull
      - run: docker-compose build
      - run:
          command: |
            mkdir -p ~/caches
            docker save $(docker images -q) -o ~/caches/images.tar
      - save_cache:
          key: docker-{{ .Branch }}-{{ checksum "docker-compose.yml" }}-{{ checksum "Dockerfile" }}
          paths: ~/caches/images.tar
  test:
    machine: true
    # parallelism: 3 # 並列化したいときはparallelismを利用する
    steps:
      - checkout
      - run: pip install docker-compose
      - restore_cache:
          key: docker-{{ .Branch }}-{{ checksum "docker-compose.yml" }}-{{ checksum "Dockerfile" }}
          paths: ~/caches/images.tar
      - run:
          command: |
            set +o pipefail
            docker load -i ~/caches/images.tar | true
      - run: docker-compose pull # 早い
      - run: docker-compose build # 早い
      - run: お好きなテストコマンド
workflows:
  version: 2
  build:
    jobs:
      - generate_cache
      - test:
          requires:
            - generate_cache

こんな具合でgenerate_cacheでdocker-compose周りの遅い処理を片付けてしまって、testを並列化することが出来る。

28
12
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
28
12