概要
Rails+docker-composeでCircleCi2.0の高速化のtipsをメモ
キャッシュを活用する
docker image のキャッシュ
docker-compose.yml
, Dockerfile
等の checksum
を使って save_cache
することで、次回以降の処理をキャッシュされたdocker image からコンテナを立ち上げることができます
md5sum $(find ./-name "Dockerfile*") > /tmp/dockerfile-md5sum`
とすることで、ワイルドカードを指定してプロジェクトディレクトリ内の Dockerfile*
の checksum
の値を用いてキャッシュすることも可能です
下記例では、docker-compose.yml
と Gemfile.lock
と Dockerfile
の checksum
を組み合わせた値 で key
を作成し、
key
に該当するデータがあれば rails
のimageを復元し、なければビルド&キャッシュするようにしています
- run:
name: generate Dockerfile checksum
command: md5sum $(find ./-name "Dockerfile*") > /tmp/dockerfile-md5sum
- restore_cache:
name: restore rails image cache
key: docker-{{ checksum "docker-compose.yml" }}-{{ checksum "Gemfile.lock" }}-{{ checksum "/tmp/dockerfile-md5sum" }}
paths: ~/caches
- run:
name: build rails image
command: |
if [ ! -f ~/caches/rails.tar ]; then
docker-compose build rails
docker-compose run rails bundle install
docker-compose up -d rails
docker save rails > ~/caches/rails.tar
else
docker load -i ~/caches/rails.tar
fi
- save_cache:
name: save rails image cache
key: docker-{{ checksum "docker-compose.yml" }}-{{ checksum "Gemfile.lock" }}-{{ checksum "/tmp/dockerfile-md5sum" }}
paths: ~/caches
テストデータのキャッシュ
テストの実行に初期データ等が依存していて、かつ初期データ作成にかかる時間的コストが大きい場合は
初期データをdumpしてキャッシュすることで時間短縮ができます
下記例では、db/seeds.rb
と db/schema.rb
と factory-girl
に記述したコードの checksum
を組み合わせた値 で key
を作成し、key
に該当するデータがあれば dump
されたデータを復元し、なければデータ作成& dump
するようにしています
- run:
name: generate factory-girl checksum
command: md5sum $(find ./spec/factories -name "*.rb") > /tmp/factory-girl-md5sum
- restore_cache:
name: restore db dump
key: db-{{ checksum "db/seeds.rb" }}-{{ checksum "db/schema.rb" }}-{{ checksum "/tmp/factory-girl-md5sum" }}
paths: ~/caches/dump_data.sql
- run:
name: setup db data
command: |
if [ -f ~/caches/dump.sql ]; then
cp -f ~/caches/dump.sql ~/tmp/dump.sql
docker-compose exec db bash -c "mysql -u root < /sql/dump.sql"
else
mkdir -p ~/caches
docker-compose run rails rails db:create RAILS_ENV=test
docker-compose run rails rails db:migrate RAILS_ENV=test
docker-compose run rails rails db:seed RAILS_ENV=test
docker-compose exec db bash -c "mysqldump -u root -A > /tmp/dump.sql"
cp -f ~/tmp/dump.sql ~/caches/dump.sql
fi
- save_cache:
name: save db dump
key: db-{{ checksum "db/seeds.rb" }}-{{ checksum "db/schema.rb" }}-{{ checksum "/tmp/factory-girl-md5sum" }}
paths: ~/caches/dump.sql
Artifactsにdumpしたデータを保存しておけばローカルのテストでもテストデータの作成時間を削減できて開発効率が上がりそうですね!
テストを並列化する
テストの並列化をしてくれるGemがいくつかあるので、導入することでテスト時間を短縮化できます
多くのGemは
- 並列化する数だけテスト用のdatabaseを作成
- スレッドを立ててRspecを並列実行
をしてくれます
代表的なGemとして、
などがあります