最近は、WebAPI や AWS のようなクラウドサービスが普及してきて、バックエンドのサーバーがなくても、Web サービスが公開できるようになってきました。
今回は AWS のS3 にある Static Website Hosting 機能を使って AngularJS で作成した SPA(Single page application)をホスティングさせてみました。
割と S3 でのサイト公開は簡単なので楽勝かと思いきや・・・
いろいろまじめに考えると手こずるものですね。
S3 での SPA 公開
S3 でのサイト公開は非常に簡単です。次の 3 ステップで即公開できます。
(「S3 サイト公開」などで検索するといくつか記事がヒットすると思いますので参考にしてください。)
- S3 上に Bucket を作成する。
- AngularJS で作成した SPA をアップロードする。
- Bucket の Static Website Hosting を ON にする。
Static Website Hosting を ON にすることでアクセス可能な URL が取得できます。
アクセスした際に「AccessDenied
」エラーになる場合は、アップロードしたファイルのPermissions
がEveryone アクセス可能になっていないことが多いです。
しかし、このEveryone アクセス可能状態はあまりいい状態ではありませんので、CloudFront を利用します。
(後で紹介しますが、S3 は CloudFront 経由のアクセスのみ有効にする設定を推奨します。)
S3 の Everyone アクセス可能は Apache の設定漏れで、ファイル一覧が見えてしまっている感覚に似ていて落ち着きません w
他にも、S3 で公開した場合に問題になりそうな部分について紹介します。
S3 での SPA 公開で問題になりそうなところ
S3 の Static Website Hosting 機能はお手軽で非常に魅力を感じるのですが、Web アプリケーションを想定した場合、次のような問題がありそうです。
- アクセスを
HTTPS
に限定できない。 - URL に「
/
」を指定した場合、S3 上のフォルダを参照してしまいエラーとなる。(結果「/index.html
」まで含める形に・・・) - 「
/
」以外の URL(「/hoge」とか)でアクセスした場合に403(access denied)
エラー(2015/01/20 追記) - 他にもあった気がするが、忘れた。
という訳で S3 のみのお手軽ホスティングは、コーポレートサイトのような静的コンテンツ向きな気がします。
CloudFront の利用
そこで利用するのが CloudFront です。いろいろ探していたら、こちらの記事が参考になりました。ありがとうございます!
[CloudFront + S3]特定バケットに特定ディストリビューションのみからアクセスできるよう設定する | Developers.IO
手順としては次のような形です。
- CloudFront 上に Distributions を作成
- Origin Domain Name に S3 の Bucket を指定
- Restrict Bucket Access で「Yes」を設定して S3 へのアクセスを制限
これで CloudFront 経由で S3 へアクセスすることができますが、SPA をホスティングするに当たって追加で以下の設定をしました。
General > Default Root Object
Default Root Object
に「index.html」を設定します。これで「/
」でアクセスした際に、エラーにならず「index.html
」を呼び出すことができます。
しかも、デフォルトの(*.cloudfront.net)ドメインであれば SSL 証明書までついてきます。
まじで至れり尽くせりです。
Behaviors > Viewer Protocol Policy
新しい Behavior を作成してViewer Protocol Policy
にてRedirect HTTP to HTTPS
を選択します。これで HTTP でアクセスされた場合に、HTTPS にリダイレクトすることが可能です。
(あまりこだわりなければPath Pattern
はDefault (*)
1 つで事足りるはず。)
CloudFront 利用上の注意点
CloudFront を利用すると幸せになれるのですが、1 点注意点があります。それはキャッシュです。
CloudFront の本質は CDN なので、コンテンツをキャッシュします。しかもデフォルトでは24h キャッシュを保持するので、S3 上にアップロードしたファイルは最大 24h 変更されません。
Invalidations を利用して Cache をクリア
CloudFront には Invalidations というキャッシュクリアをする仕組みがあるので、これを使って CloudFront に対してキャッシュのクリアを指示します。
(ただ、5〜10 分くらいかかります。リアルタイムではないです。)
CloudFront で Distributions を選択すると「Invalidations
」というタブがあるので、ここで「Create Invalidation
」ボタンをクリックします。
クリアするファイルを指定する必要があるので、例えば「/index.html
」とか入力します。
私の場合、フロントのリソースは結合&minify&バージョニングして最適化してしまうので、普段はindex.html
だけで十分です。
あとはキャッシュがクリアされるまで気長に待ちましょう。
まとめ
「S3 + CloudFront」を使うことでお手軽に AngularJS で作成した Web アプリケーションをホスティングすることができました。しかも勝手にスケールするし、クラウドサービス偉大過ぎます。
しかし、上には上がいる!
今回の「S3 + CloudFront」はまだ大関構成なようですね。個人的には頑張ったと思うのですが。。。orz
こちらの記事を読むと、この上の「S3 + CloudFront + Route53」横綱構成があるようです。
AWS における静的コンテンツ配信パターンカタログ(アンチパターン含む) | Developers.IO
もっと稽古します。
(2015/01/20 追記)
/
以外の URL でアクセスした場合に403(access denied)
エラーになるのですが、CloudFront Distributions の Error Pages 設定で、403 エラーの場合のエラーページを/index.html
にすることで回避することができましたー。
うぇーーーーい!!って無理矢理感が半端ない w