Nuxt.js で作成した静的サイトを S3 + CloudFront でホスティングするパターン

Nuxt.js で SSR を使わない静的サイトを生成(nuxt generate)して S3 で安価にホスティングする場合、「各ページに対して index.html ファイルが生成されるが、リンクの URL では index.html は省略されるため、そのままでは Not Found になってしまう」という課題がある。通常の Web サーバーには、例えば Apache では DocumentIndex、nginx では index というように、ファイル名が省略された場合にデフォルトのファイル名を配信する設定があるが、それ相当の動作が必要となる。

実現方法にはいくつかパターンがあるようなので、詳細はそれぞれの解説ページに任せるとして、それらを整理してみた。

参考

構成パターン

1. S3 で Static website hosting をおこなう

  • 大量のアクセスが発生しない、かつ HTTP だけで良い場合はこれが最もシンプル。
  • Static website hosting の「Index document」設定に「index.html」を設定する。
  • カスタムドメインで公開する場合は、バケット名を FQDN にする必要がある。

S3 で Static website hosting をおこなう

参考

2. S3 で Static website hosting をおこない、CloudFront 経由で公開する

  • 1 に加えて、CloudFront から S3 で Static website hosting した URL を Origin とする。
  • S3 の Static website hosting にも直接アクセスできてしまう。
  • S3 への直接アクセスを制限する手段はあるが、弱い方法しかない? HTTP での直接アクセスを絶対にさせたくないといった場合は注意。
  • CloudFront からのリクエストに特定のカスタムヘッダを付与し、S3 でそれをチェックするなど。
  • CloudFront の Edge は多数あり変動するので IP 制限はあまり現実的ではない。

S3 で Static website hosting をおこない、CloudFront 経由で公開する

参考

3. CloudFront のエラーページ設定で index.html を返す

  • S3 での Static website hosting はおこなわず、CloudFront から S3 バケットを Origin とする。
  • index.html が省略されて 403 となった場合に表示するエラーページとして、index.html を返すように設定する。
  • 余談) CloudFront に「Default Root Object」というそれっぽい設定はあるが、これは本当にルートにしか効かないので役に立たない。
  • 意味的にはエラーページとして表示することになるので、少し気持ちが悪い。(個人の感想です)

CloudFront のエラーページ設定で index.html を返す

参考

4. Lambda@Edge で index.html への書き換えをおこなう

  • CloudFront へのアクセスをフックして独自の処理を加えられる Lambda@Edge を使い、index.html を付与して Origin にリクエストする。
  • 設定が比較的面倒で、Lambda のぶん追加コストがかかる。

Lambda@Edge で index.html への書き換えをおこなう

参考