前置き
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 pull
とdocker-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を並列化することが出来る。