Blog

Serverless Nextjs Pluginを試した所感について


 こんにちは、気づいたらいつの間にか新卒三年目になっていた宮本です。近所の書店が改装になり、スペースも広くなるとのことなのでそれが最近は楽しみです。

 さて、今回は最近業務で触る機会のあったServerless Nextjs Pluginについてご紹介したいと思います。

内容3行まとめ

  • Serverless Nextjs PluginはNext.jsのサーバレスモードのインフラ構成を提供してくれるツール
  • 簡単にデプロイできるが、細かいチューニングをしようとすると一部痒いところに手が届かない箇所がある
  • まだまだ開発・改善中なので今後に期待大

Serverless Nextjs Pluginとは


 Next.jsは言わずと知れたReact用のフレームワークでしょう。SSGやSSRに、画像最適化機能やapi作成機能などなどをほとんど手間なく簡単に実現することができ、とても便利なフレームワークです。

 このNext.jsですが、Next.js 8からサーバレスモードというものが実装されました。従来であればひとつのサーバ上に乗せて動作させるものを、AWS Lambdaのような環境に機能ごとに分割して動作させられるというものです。

 利点については、

“serverless allows for distributed points of failure, infinite scalability, and is incredibly affordable with a “pay for what you use” model.”
引用: https://nextjs.org/blog/next-8#serverless-nextjs

とのことで障害となる箇所の分散や、スケールアップのしやすさ、コスト面で嬉しいですね。

 さて、「やったね!」と言いたいところですが、ここで一つの問題が出てきます。あくまでNext.jsが提供しているのはサーバレスモード用のファイルのビルドまでであり、そこからインフラ構成を作成しデプロイする部分に関しては開発者任せでした。まあ、そりゃそうですよね……。ですが、いざサーバレスモードで運用できるようにするためにインフラ構成を考えるぞ、となるとこれがなかなかに手間です。機能ごとにファイルを分割しているため、当然機能の分だけリソースが必要になり、なかなか複雑で手強い構成になりそうですね。

 そこで登場するのが、Serverless Nextjs Pluginです。これはNext.jsのサーバレスモードでビルドしたファイル群に対し、うまい具合にCloudFront + Lambda@edge + S3構成のインフラ環境を構築してくれるツールです。この辺りの経緯については、公式リポジトリのissueに詳しく書かれています。
引用: https://github.com/serverless-nextjs/serverless-next.js/blob/master/img/arch_no_grid.png

 Serverless Nextjs Pluginでは基本的に3つのLambda@Edgeに機能を分割してデプロイし、静的ファイルはS3に配置し、CloudFrontを通してアクセスするという環境を自動で用意してくれます。なんと全てデフォルト設定でデプロイするなら、ファイルをひとつ追加して2行書くだけという脅威の手軽さです。

使用してみた所感


 では、業務で利用してみて感じたメリットとデメリットです。

メリット

  • 簡単にサーバレスモードのNext.jsをAWS上にデプロイすることができる
    • 元のNext.jsプロジェクト側には変更が不要
  • CloudFront + Lambda@edge構成なので、世界中から高速にアクセス可能
  • 現在も開発中であるため、機能の改善が見込める

簡単にサーバレスモードのNext.jsをAWS上にデプロイすることができる


 まずはメリットからですが、やはり真っ先に挙げるべきなのはその手軽さでしょう。設定ファイルをひとつ追加し、コマンドひとつでデプロイできるのは魅力です。とりあえずデプロイするだけであれば、それこそサーバレスモードではないNext.jsよりも簡単にデプロイできます。

CloudFront + Lambda@edge構成なので、世界中から高速にアクセス可能


 次に、Serverless Nextjs Pluginではインフラ構成としてCloudFrontとLambda@edgeを採用しています。世界中のエッジロケーションで動作するLambda@edgeにアプリケーション本体が載っていることで、特定のAWSリージョンに依存せず高速に動作可能です。

現在も開発中であるため、機能の改善が見込める


 現在API Gateway + Lambda構成でサーバレスモードのNext.jsを動作させられるように開発を進めている最中のようです。また、以前Next.js 12.9にアップデートするとNext.jsのAPI routes機能が壊れてしまうというバグがありましたが、半月ほどで修正されたりしています(API routes return CloudFront 503 on next 12.0.9 · Issue #2327 · serverless-nextjs/serverless-next.js)。
 しかし、その一方で残念ながらコントリビュータ不足にも悩んでいるご様子……。

デメリット

  • 各種設定において、痒いところに手が届かないことがある
    • 開発が追いついておらず、最新の設定項目が利用できない
    • CloudFrontの項目の更新の挙動が独特
    • アプリケーション本体がLambda@edgeに乗っていることで発生する問題がある
  • 現状はAWSにしかデプロイできない

 次にデメリットですが、主に設定周りでやや苦労する箇所が多かったです。

各種設定において、痒いところに手が届かないことがある

  • 開発が追いついておらず、最新の設定項目が利用できない

 CloudFront関連の設定だと現行のバージョンではキャッシュポリシーを設定する項目がありません。キャッシュについてはポリシーではなくビヘイビア設定ごとにヘッダーやクエリ、cookieを指定する旧来の手段では設定することが可能です。今後もAWS側での機能追加はあると思いますが、デプロイできなくなってしまうようなクリティカルな場合を除き、なかなかすぐには対応されないかもしれません。

 また、その一方でカスタムレスポンスヘッダーポリシーは最新のバージョン3.7.0で以下のような形で設定できるようになっているものの、READMEにはまだ記載が存在しなかったりします。Serverless Next.js Pluginのリポジトリはモノレポ構成になっており、内部でデプロイに使っている別のServerless ComponentのソースコードとREADMEもあるので、場合によっては確認することをお勧めします。設定次第では、そちらのREADMEには記載が存在するものもあります。
  • CloudFrontの項目の更新の挙動が独特

 CloudFrontの設定を更新する際の挙動も、やや直感とは異なる動きをしていました。設定はserverless.yamlという設定ファイルに記述しますが、これがなかなかの曲者。たとえば一度設定したビヘイビア設定をserverless.yamlから削除しデプロイしても、CloudFrontからそのビヘイビア情報は消えません。消すためには手動でコンソールを変更する必要があり、初めは結構混乱しました。他にも同じように利用しなくなったオリジン設定も残り続けるなど、少々厄介な点があります。

 この辺りの挙動については、ドキュメントも完全に整備されているわけではないため、必要に応じてGitHubのコードを確認する必要が多々ありました。隅々までCloudFrontや設定しようとした場合は、何かと辛くなる部分が多いです。
  • 現状はAWSにしかデプロイできない

 次にこれはServerless Nextjs PluginというよりもAWSの機能としての注意点ですが、アプリケーション本体がLambda@edgeに乗っていることに注意が必要です。Lambda@edge上で動作しているため世界中どこからでも高速にアクセス可能ですが、一方で環境変数が使えなかったり、Lambda Layersが使えなかったりと制約があります。

 もっとも、環境変数についてはコードのビルド時に自動的に値が埋め込まれるため基本的には気にする必要もありません。しかし、Next.jsのビルド時のtargetとしてexperimental-serverless-traceを選択すると、ライブラリ内の環境変数は値が埋め込まれずにそのまま残るため、一部のライブラリが動作不良を起こす可能性があります。監視ツールとしてSentryを組み込むための対応としてtargetにexperimental-serverless-traceを設定したところ、見事に引っかかりました。他にもLambda@edge特有の制限などが存在するので、AWSのドキュメントも確認しつつご注意ください。

 また、先にも述べましたが現時点ではAWSへのデプロイしか対応していないため、GCPやAzureを利用している場合は使えないという点にも注意が必要です。

おわりに


 以上がServerless Nextjs Pluginを触ってみた所感になります。

 全体の文の比率を見る限りなんとなくお分かりいただけるかと思いますが、残念ながら徹底的にチューニングしようとするとどうしても辛くなる部分が出てくるというのが現在の印象です。しかし、簡単に個人のプロジェクトなどでちょっとNext.jsをデプロイする場合などは十分な機能が揃っていると思います。
 Serverless Nextjs Plugin自体が今後も開発を続けていくプロジェクトであるため、現状感じる不満点なども解消される可能性もあります。個人的には、特にAPI Gateway + Lambda構成でのNext.jsアプリケーションに期待大です。また、現在は内部的にはServerless Componentのベータ版を利用してインフラ構成をデプロイしているようですが、将来的には内部でCDKを利用することも考えているらしく、変化しそうな部分も多そうです。

 もしNext.jsを利用する機会があれば、Serverless Nextjs Pluginも試してみてください。

参考

We are hiring!

ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! Tech TalkやMeetUpも開催しております!
こちらもお気軽にご応募ください!