こんにちは、開発本部の宮内です。
さて、これまで弊社のオンライン診療アプリ「CLINICS」では、ローンチ時よりHerokuを利用しておりました。 Herokuとは、PaaSの一種でWebアプリケーションを簡単にデプロイ、ホスティングできるサービスです。 ある程度の制約はつきますが、(大体の制約は金で解決できるので)使っているかたも多いのではないでしょうか。
今回、事情によりHerokuからAWS Elastic Beanstalk(以下、EB)へ移行することになりましたので、そのあたりでやったことを共有できればと思います。
Private PaaSにしないの?
まずはじめに移行にあたり、Priavte PaaSを構築する方法を模索しました。 ですが、これらのクラスタの構築はできても、専任の(Ops|SRE|インフラ)チームがいないため、日々の管理や運用に手が回らないだろうという思いから、Private PaaSの構築は見送りました。 この辺りは今後チーム人数が増えたら挑戦していきたいです…。
検討時、参考にしたリンク
なぜAWS Elastic Beanstalkにしたの?
EBにはRailsやSinatraで作成されたウェブアプリケーションを実行するためのRubyプラットフォームが予め用意されております。 ただし、今回の移行では、アプリケーションへの変更を一切加えずに行いたかったため、Rubyプラットフォームを利用しませんでした。 代わりにDockerコンテナが実行できるプラットフォームがあったため、そちらを使うことにしました。
herokuishでDockerイメージを作成
アプリケーションのDockerイメージ化には、gliderlabs/herokuishを使いました。 これはbuildpackを使いアプリケーションをslug化したり、slugを実行するためのツールです。
Dockerイメージ作成の手順は以下の通りです。
1. herokuish buildpack build
と herokuish slug generate
でアプリケーションをslugにする
2. herokuish slug import
でslugをインポートして完成
それでは、それぞれ簡単に説明していきたいと思います。
アプリケーションをslugにする
docker pull gliderlabs/herokuish docker run \ -v "/path/to/app:/tmp/build" \ -v "/path/to/cache:/tmp/cache" \ -v "/path/to/slug:/tmp/slug" \ gliderlabs/herokuish \ /bin/bash -c 'herokuish buildpack build && herokuish slug generate && herokuish slug export > /tmp/slug/slug.tgz'
herokuishは特定のディレクトリに対して処理を行います。↑ではビルドするアプリケーションまでのディレクトリパスを/tmp/build
にマッピングしています。
/tmp/cache
はbuildpackが利用するキャッシュ置き場です。このディレクトリを次回以降のビルドでもマッピングしておくとビルドの高速化が見込めます。
最後の/tmp/slug
はビルドしたslugをコンテナからホストへコピーするために指定しています。(これはherokuishで用意されてるものではなくコンテナからホストへファイルをコピーする方法を悩んだ末のアドホックな対応です…)
他にも様々なディレクトリがあります。詳しくはドキュメントをご覧ください。
slugをインポートする
次に作成したslugを使いアプリケーションのDockerイメージをつくります。
cd $(mktemp -d) mv /path/to/slug/slug.tgz . echo ' FROM gliderlabs/herokuish COPY slug.tgz /tmp/slug.tgz RUN cat /tmp/slug.tgz | herokuish slug import && rm /tmp/slug.tgz EXPOSE 5000 ' > Dockerfile docker build -f Dockerfile .
docker build
時にContextとしてカレントディレクトリ全体が送られるため、一時ディレクトリを作成しその中でdocker build
を行っています。
終わり
CLINICSでは上記のような手段で作成したDockerイメージをAmazon EC2 Container RegistryにアップロードしEB上で実行しています。
本来であれば、アプリケーションをslugにする部分と、slugをインポートする部分を分割しなくても良いと思いますが、CircleCIでDockerイメージを作成する関係上でこのような方法になりました。
先日GAとなったCircleCI 2.0にはまだ対応できていないので、今後の課題としたいと思います。
お知らせ
メドレーでは、CLINICSだけでなく、医療介護の求人サイト「ジョブメドレー」、医師たちがつくるオンライン医療事典「MEDLEY」、口コミで探せる介護施設の検索サイト「介護のほんね」などのプロダクトも提供しています。これらのサービスの拡大を受けて、その成長を支えるエンジニア・デザイナーを募集しています。
メドレーで一緒に医療体験を変えるプロダクト作りに関わりたい方のご連絡お待ちしております。