Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

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にはRailsSinatraで作成されたウェブアプリケーションを実行するための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」、口コミで探せる介護施設の検索サイト「介護のほんね」などのプロダクトも提供しています。これらのサービスの拡大を受けて、その成長を支えるエンジニア・デザイナーを募集しています。

www.medley.jp

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