
Reactを使ったSPAの運用方法(デプロイ、ロールバック、メンテナンス)
はじめに

ReactなどでSPAを開発して公開する場合、AWSではCloudFrontとS3の構成にしましょうという情報がとても多く出てくると思います。
S3のレプリケーション機能でS3をマルチリージョンで運用し、CloudFrontのOriginGroupに、それぞれのS3バケットを指定すると、AWSのリージョン障害にも対応でき、全リージョン障害ではない限りは、継続してサービスを提供できる障害にとても強いインフラ構造になるためです。
しかし、紹介される多くの情報では、継続して機能の追加や改修がある場合、どうすれば良いのかの情報があまりありません。SPAは、データが揃っていない状態でもページを表示することのできる、リッチなUIを実現する上で重要な概念です。Reactで開発したSPAなら、HTMLやCSSなどの静的なファイルを配信するだけで済みます。
本記事で紹介する、機能要件

そこで今回は、以下の要件を満たす方法をご紹介します。
指定したタイミングで公開される
問題が発生したときには動作していたバージョンに戻せる
使われなくなったコンテンツは削除できる
SPA(Single Page Application)について
SPAは、一枚のページでWebアプリケーションを機能させるための概念です。通常であれば遷移が必要なスケールの大きいコンテンツを抱えていても、SPAならページ上でコンテンツを更新し、遷移を行うことなくコンテンツを切り替えられます。
SPAの強みは、ユーザビリティを向上させられる点です。操作が必要になるたびページの更新が必要な設計は、ユーザーにとって面倒が大きく、離脱を促してしまうこともあります。一方でSPAがあればこのような負担をユーザーから排除できるため、ストレスなくWebアプリを体験してもらうことが可能です。
またサーバーとの通信量を抑えられるなど、パフォーマンスそのものを高められる強みも有しています。
Reactとは
Reactは旧Facebook社が開発したJavascript向けのライブラリです。ユーザーインターフェースを向上させるためのパーツを構築するために用いられており、世界トップのWebサービス群で採用されています。
Reactがポピュラーなライブラリなのは、オープンソースで提供されていることも背景に挙げられます。無料で誰でも使える導入のしやすさと、世界で使用されている信頼性の高さは、アプリ開発においては無視できない強みです。
既存のソースコードを大きく変更することなく実装ができる使いやすさも魅力で、途中からReactに置き換えたいという場合でも、安心して頼ることができます。
CloudFrontの役割
CloudFontは、静的コンテンツや動的コンテンツを迅速に表示するためのAWSのサービスです。CDN(Content Delivery Network)の一種として知られており、サーバーへの負荷がかかりやすい時間帯や、負荷の大きい大容量コンテンツを扱う場合でも、安定した速度でコンテンツをユーザーに配信することができます。
コンテンツ配信の高速化は、大容量データを扱うようになってきた近年において、重要な課題です。CloudFontは、コンテンツが格納されているオリジンサーバーと、世界に分散しているエッジロケーションを組み合わせることで、小さい負荷での高速なコンテンツ配信を可能にします。
失敗例

要件を満たすように初めに行った方法は、次のコマンドの通りにアプリをビルドし、バージョンごとにS3に保存する方法です。
npm run build
aws s3 sync build s3://my-bucket/${VERSION}
CloudFrontのオリジンパスに${VERSION}を指定することで、コンテンツを切り替える方法しました。
発生した問題点
この方法で新しいバージョンのデプロイを行うと、ブラウザでページを再読み込みしたタイミングで画面が真っ白になるという事象が発生しました。
原因は、古いキャッシュが、新しいバージョンに存在しないファイルを利用するため、404エラーとなり、この問題が発生したようです。キャッシュがすべて新しいものに切り替わると、正常にページが表示されるようになりました。
成功した方法

そこで、古いキャッシュを利用しても古いファイルを返すことができる構成を検討しました。検討した結果、URLのパスにバージョンを含めるようにしました。
バージョンを含める方法
export PUBLIC_URL=/$VERSION/
npm run build
aws s3 sync build s3://my-bucket/${VERSION}
aws s3 cp s3://my-bucket/${VERSION}/index.html s3://my-bucket/
バージョンの切り替えは、各バージョンの index.html を RootIndexと置き換えることで実現しました。
この構成のメリット
Index.htmlを差し替えることで、バーションを切り替えることができるので、キャッシュが切り替わるタイミングで新しいバージョンになります。
また、古いキャッシュを参照しても、ファイルが存在するためエラーになりません。ディレクトリごとにバージョンを分けているので、既に使わないバーションを簡単に削除することができます。
まとめ

SPAをどのように運用していくのかの情報があまりなく、私が実施した方法をご紹介しました。ぜひお試しください。
最後に、当社ではAWSを8%割引でご利用いただける 請求代行サービス や AWSの運用監視サービス、 AWSのコスト・構成・可用性の無料最適化診断サービスなどをご提供しています。