株式会社メドレーDeveloper Portal

2017-09-22

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 イメージ作成の手順は以下の通りです。

  1. herokuish buildpack buildherokuish 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」、口コミで探せる介護施設の検索サイト「介護のほんね」などのプロダクトも提供しています。これらのサービスの拡大を受けて、その成長を支えるエンジニア・デザイナーを募集しています。

https://www.medley.jp/recruit/creative.html

メドレーで一緒に医療体験を変えるプロダクト作りに関わりたい方のご連絡お待ちしております。

株式会社メドレーDeveloper Portal

© Medley Developer Portal