【新米エンジニア学習記録④】Next.jsのデプロイⅡ

EC2を使わずにLambda Web Adapterを使ってNext.jsを動かしたい

 

こんにちは。
前回はNext.jsで作成した簡単なアプリケーションをAWSへデプロイしました。

前回使用したEC2はサーバを構築するため料金が割高になります。
コストを落とすことを考える際にはサーバのスペックなど、過剰スペックではないかというところから考えると思います。

でも、例えばポートフォリオとして長期間稼働しておきたい場合や、趣味で利益は出ないけどWebからアクセスできるアプリケーションを稼働させておきたい場合、EC2にも無料枠はありますが、どうしてもその範囲を超えてコストが掛かってきます。

簡単なアプリケーション作成であれば、S3+Lambdaを使用するという手段を取ることができますが、前回デプロイしたNext.jsでは動的ルーティングなどの一部機能が使えなくなります。

そこで今回はLambda Web AdapterというLambda拡張ツールを使って、サーバレスにNext.jsを動かしましょう!

・LambdaでNext.js動かすってどういうこと?
・データとかどこに置くの?S3?
・そもそもAWSのLambdaの拡張ツールって何よ

といった、何それ思考状態です。

 

一応今回の対象者(私の現在の状態)としては、

・Next.jsについて書き方はともかく、ルーティングなど基本的なことは理解している
・Lambda+API GatewayでAPIを作成したことがある

それでは早速、どこかのサイトを参考にすれば何とかなるでしょ思考でやっていきましょう。

 

参考サイト
Next.jsをLambda Web Adapterでサーバレスに動かしてみた[AWS SAM] #lambda – Qiita

今回はこのサイトをベースに使って進めていきます。
分からなかったら容赦なくベースサイトを切り替えていきます(-“-)

 

コンテナって何よ。
私、一応、応用情報もっているんですけど、サーバ仮想化の中にコンテナ型っていうのがあったなぁ、程度の知識ですね……。
【図解】サーバーの仮想化って?3種類もあるの?ホスト型?ハイパーバイザー?コンテナ?違いは? | 「そんなか」サイト

分からない人のためにも一緒に勉強しましょう😢
参考になりそうなサイトを探してきます。
今さら聞けないコンテナとは #初心者 – Qiita

 

 

うん、分からん!

日本語は分かるし、言っている意味も何となく分かりますが、全然頭に入ってきません。
とりあえず、Lambda Web AdapterというのはNext.jsなどのWebフレームワークをローカルでやってる感じでそのまま環境を意識せずに動かせる的な感じなのでしょうか……。感じが多過ぎる(笑)

もう次に行きます!

 

 

AWS SAM CLI??
さむくり?何それ美味しいの?
いきなりわけ分らんもんを出すなぁ!!

とりあえず、調べましょう。

 

AWS SAM CLI 再入門 2021.08 #lambda – Qiita

 

お腹が痛くなってきました。

そもそもCloud Formationが何か分かりません。
ちゃんと調べますが、Lambda Web Adapterまで帰ってくることはできるのでしょうか。

 

【AWS】CloudFormationの概要を5分で理解する #IaC – Qiita

 

少ない知識を元に訳すと、容量とかスペックとか自動で増やしたり、減らしたりできるもので、
Cloud Formation事態に料金はかからないよ。
ってことかなと。

Cloud Formationに関しては何となく理解できましたが、
Cloud Formationの拡張機能で、Lambda や API Gateway, DynamoDB のようなサービスを活用したサーバーレスアプリケーションのデプロイに特化する。
というのが全然ぴんときません。
例えるなら、寿司屋の拡張機能で、うどんがメニューに追加されますなら、ぴんとくると思うんですが、
寿司屋の拡張機能で、通常のシャンプーの代わりに髪が痛みにくいシャンプーに変更されます。
と言われても、全然ぴんとこないと思います。
今、正にそんな感じです。

声を大にして言いたい。
お前、自動でプロビジョニングするサービスじゃなかったんか!何、デプロイ始めてんねん!

 

まあ、分からないということが分かったので、よしとしましょう。

SAM CLIのサイトに戻ります。

GitとDockerは分かる。理解しているとは言ってない。
でもAWS CLIってなんだよ!

調べてきます……。orz

 

AWS CLIのインストールと基本的な使い方 #aws-cli – Qiita

 

CLIってコマンドラインインターフェースってことみたいですね。
それならそうと早く言ってほしかった。
 

長文苦手な人に分かりやすく言うなら、Webからの画面操作じゃなくて、コマンドプロンプトとか自分のパソコンからのコマンドでAWSを操作できるよってことらしいです。
Web画面操作ももちろん自分のパソコンからではあるんですけど、ローカル的な意味合いで使ってます。AWSへ接続したコマンドプロンプトが果たしてローカルなのかと言われると違う気がしますが(笑)

 

サイトを参考にしてAWS CLIをインストールしましょう。

Windowsの場合、AWS CLIのインストール説明ページからインストーラをダウンロードする必要があるみたいです。
手順はこのページに書いてありました。
AWS CLI の最新バージョンのインストールまたは更新 – AWS Command Line Interface

 

あっさりとインストールできました。

 

AWS CLIの初期設定で、どうやらアクセスキーが必要みたいでして、AWSを見ているとそれっぽいのがあったので、作成していきます。

 

アクセスキーを作成を押すとこのような画面が出てきました。

どうやら、ルートユーザのアクセスキーを作るとそれが漏洩した場合、セキュリティ的に危ないからIAMでユーザを作った方が良いみたいですね。
 

IAMでユーザ作成をするとそのユーザにログインし直さなくてもルートユーザから直接アクセスキーを作成できるようです。

 

作成を完了するとアクセスキーと、シークレットアクセスキーが発行されるので、その2つを使って初期設定を完了させます。

 

今回はサイトのお手軽コースを使用させてもらいました。

 

やっとAWS SAM CLI のインストールへ戻ってきました。

URLを打ち込んで、インストーラをダウンロードする必要があるみたいですね!

 

 

おいおい((((oノ´3`)ノ

 

調べます。

 

ここから普通にインストールできそうです。
AWS SAM CLI のインストール – AWS Serverless Application Model

 

インストールできました。

 

samコマンドも問題なく使えます!
これでやっとLambda Web Adapterへ戻れる……。

 

ここまでのボリュームが大きくて脳死でやりたいので、手順通りに行きます。

 

問題なくできました!

 

 

 

npm run build

で、問題なくstandaloneフォルダが作成されました。

 

 

プロジェクトのディレクトリ……、こういうことでしょうかね。

 

 

急によく分からないことを言い始めました。
コンテナイメージとは何でしょうか?

「分からないことは調べます。」システムエンジニアの大切な心得です。

 

これが参考になりそうです。
初心者向け!docker image(イメージ)とは?コンテナとの違いは何?

コンテナを作るための設計図をAWSのECR Public Galleryから選ぶということでしょうか。

手順と同じpublic.ecr.aws/docker/library/node:22.11.0-slimを選び、Copyを押しましたが、使い方が分かりません。
理解している人は理解していない人の気持ちを分かってくれません😢

AWSのECR Public Galleryの使い方で検索したら、使い方が分からないでしょうか。

 

これが参考になりそうです。
【AWS】Amazon ECR ~ AWS ECR Public Gallery ~ – プログラム の超個人的なメモ

このサイトによれば、
dockerfileというもので使用するとのこと、

ベースで使っているサイトでもdockerfileを作成するという文言と、ファイルの中身について記述しているものがありました。

 

つまり、
dockerfileを手動で作ってね!dockerfileに記述する内容はこれだよ。FROM部分のnode:22.11.0-slimなんかはECR Public Galleryを見て、好きなやつに書き換えてね!ってことっぽいです。

ちゃんと書いてよ!!

知識がない人からしたら、
dockerfileを作る必要があるので、ECR Public Galleryから好きなやつ選んで何かしたら、dockerfileできるよ!って思うじゃないですか。

 

気を取り直しましょう!

そもそも、dockerfileが何なのか分かりません。
調べましょう。

 

【保存版】Dockerfileの書き方|基本からコマンド一覧まで

このサイトによると、どうやら、dockerfileの名前はDockerfileらしいです。
何言っているか分からないかもしれませんが、拡張子もなくDockerfileでいいみたいです。

 

要するに、これでOKってことですかね。

 

 

そしてこのコードを実行すれば……。

 

ビルドはできたのですが、怒られちゃいました。

 

どうやら、asが小文字だったので、大文字にしろというのと、
CMD命令をJSON形式に修正しろということみたいです。

まったく、直しておきなさいよ!

FROM public.ecr.aws/docker/library/node:22.11.0-slim AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM public.ecr.aws/docker/library/node:22.11.0-slim AS runner
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
ENV PORT=3000 NODE_ENV=production AWS_LWA_ENABLE_COMPRESSION=true
WORKDIR /app
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/run.sh ./run.sh
RUN ln -s /tmp/cache ./.next/cache
RUN chmod +x ./run.sh
CMD ["./run.sh"]

 

dockerfileを修正して、再ビルドしたら今回はWarningsが出なかったです。

 

 

これも問題なくできました。

 

そしてここでフォルダの確認を行います。

 

あれ……。

整理するために、多いファイル/フォルダと少ないファイル/フォルダを書き出しましょう。

多いファイル/フォルダ
・template.yaml
・eslint.config.mjs

少ないファイル/フォルダ
・.eslintrc.json

 

順番にいきましょう。

 

・template.yaml

今さっき、作れって言ったじゃん!

忘れてないからな!

どこに配置するかは不明ですが、困った時に考えましょう!

 

・.eslintrc.json
・eslint.config.mjs

名前が似ているからもしやと思いましたが、この2つは互換性のあるものみたいです。
気にしなくてよさそうですね。

 

これで問題なく進められると思います。
template.yamlは知りません。

 

 

問題なくビルドできました。

 

次はデプロイなのですが、怒られました。

どうやら実行するIAMの権限がなかったみたいです。

 

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"cloudformation:CreateStack",
				"cloudformation:DescribeStacks",
				"cloudformation:DescribeStackResources",
				"cloudformation:UpdateStack",
				"cloudformation:DeleteStack",
				"cloudformation:DescribeChangeSet",
				"cloudformation:CreateChangeSet",
				"cloudformation:ExecuteChangeSet",
				"cloudformation:ListStackResources",
				"cloudformation:DescribeStackEvents",
				"ecr:CreateRepository",
				"ecr:BatchCheckLayerAvailability",
				"ecr:GetAuthorizationToken",
				"ecr:PutImage",
				"ecr:TagResource",
				"ecr:SetRepositoryPolicy",
				"ecr:UploadLayerPart",
				"ecr:CompleteLayerUpload",
				"ecr:InitiateLayerUpload",
				"ecr:BatchGetImage",
				"ecr:GetDownloadUrlForLayer",
				"s3:PutObject",
				"s3:GetObject",
				"s3:ListBucket",
				"iam:CreateRole",
				"iam:AttachRolePolicy",
				"iam:PassRole",
				"iam:GetRole",
				"lambda:CreateFunction",
				"lambda:InvokeFunction",
				"lambda:UpdateFunctionCode",
				"lambda:UpdateFunctionConfiguration",
				"lambda:TagResource",
				"lambda:GetFunction",
				"lambda:CreateFunctionUrlConfig",
				"lambda:RemovePermission",
				"lambda:AddPermission",
				"lambda:DeleteFunctionUrlConfig",
				"lambda:GetFunctionUrlConfig",
				"lambda:DeleteFunction"
			],
			"Resource": "*"
		}
	]
}

最終的にこの権限で、実行できました。
実行→エラー→権限付与→実行→エラー→権限付与
の繰り返しで、半日作業でした……。
そもそもエラー原因が権限不足と突き詰めるのに1、2時間、
トライ&エラーで更に倍の時間がかかりました。
必要権限全部書いておいてよ😢

まあ、Lambdaだけは使うの分かってたんだからフルアクセス付けておけよって話なのですが。
好奇心で、最初に適当に付けておいたポリシー全部外しました☺
といっても、最初に適当に付けた10個のポリシーの内、該当したのがLambdaとS3だけという悲しい命中率です。

権限て、結構多いんですね。

 

そんなこんなで、できました!

 

感動ですね!
実はできてなくて、前回のEC2でデプロイした画像とかでは決してないです(-“-)

お疲れ様でした。

 

投稿者プロフィール

InoTomoki

関連記事

  1. AWS

    【AWS】Redash on EC2 が突然 502 Bad Gate…

  2. AWS

    【AWS】API Gatewayを使ってみる

  3. 【NextJS】Redux

  4. Docker

    【Docker】てっとり早くPHP8環境を構築する

  5. Docker

    WSL2上のUbuntuの中でDockerを動かすには?

  6. AWS

    【API Gateway】Lambda Web AdapterからWe…

最近の記事

  1. AWS
  2. AWS

制作実績一覧

  1. Checkeys