Docker上でテストを回す
最近RailsやPerlで書いたWebアプリケーションのテストをDocker上で回すようにした。
Docker周りエコシステムは沢山あるけど、まだスタンダードと呼べるものがなく、環境を整えたり、変更点をキャッチアップするコストも馬鹿にならないので、とりあえずdockerだけインストールされていれば実行出来る、一番シンプルな形に今は落ち着いている。
例えばMySQLを使うRailsアプリの場合、プロジェクト内にdocker/test/Dockerfile
を作っておいて、
FROM nkwhr/ruby-ubuntu RUN apt-get -y install libmysqlclient-dev ADD deploy.key /root/.ssh/id_rsa RUN chmod 400 /root/.ssh/id_rsa RUN echo "Host private.gitserver.com\n\tStrictHostKeyChecking no\n" > /root/.ssh/config RUN git clone -b docker git@private.gitserver.com:your/project-a.git RUN cd project-a && bundle install --without development:production -j $(getconf _NPROCESSORS_ONLN) WORKDIR /project-a ENV RAILS_ENV test CMD git pull && \ bundle install -j $(getconf _NPROCESSORS_ONLN) && \ bin/rake db:create db:migrate && \ bin/rspec
以下の様なシェルスクリプトをJenkinsなどで実行すればテストを行える。(MySQLサーバはmysql
というホスト名でアプリケーションコンテナにlinkしているので、Railsの場合は予めconfig/database.yml
でhostをmysql
に変更しておく必要がある。)
#!/bin/sh PROJECT="project-a" APP="$PROJECT/test" MYSQL="dockerfile/mysql" echo "o Preparing docker images..." docker history $MYSQL >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "--> Downloading image $MYSQL" docker pull $MYSQL fi docker history $APP >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "--> Building image $APP" docker build -t $APP docker/test/. fi echo " Done" echo -n "o Starting [mysql] --> " docker run -d --name mysql $MYSQL echo " Done" echo -n "o Running [app] --> " docker run --rm --name app --link mysql:mysql $APP result=$? echo " Done" echo -n "o Stopping [mysql] --> " docker stop mysql >/dev/null docker rm mysql echo " Done" exit $result
初回実行時はアプリケーションコンテナのイメージを生成するので時間がかかってしまうが、二度目からは差分のみの更新となるので通常の実行方法と変わらないくらいの時間で実行出来る。
pros
- dockerさえあればどこでも動く
- プロジェクト毎に言語やミドルウェアのバージョンが違っても気にしなくていい
- 関連しているアプリケーションが必要な場合も、追加でそのコンテナイメージを
run
するだけ - テスト後のゴミデータを気にしなくていい
- 少し書き換えればtestだけじゃなくてdev/prod環境としてもデプロイできる
cons
まだ々試行錯誤している段階ではあるけど、常にクリーンな環境でテストを実行出来るのは精神衛生的によい。