PaaS を Heroku から AWS Elastic Beanstalk に移行した話
こんにちは、開発本部の宮内です。
さて、これまで弊社のオンライン診療アプリ「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 イメージ作成の手順は以下の通りです。
herokuish buildpack build
とherokuish slug generate
でアプリケーションを slug にする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」、口コミで探せる介護施設の検索サイト「介護のほんね」などのプロダクトも提供しています。これらのサービスの拡大を受けて、その成長を支えるエンジニア・デザイナーを募集しています。
https://www.medley.jp/recruit/creative.html
メドレーで一緒に医療体験を変えるプロダクト作りに関わりたい方のご連絡お待ちしております。