【AWS】Next.js(SSR) を AWS(ECR + ECS + Fargate) にデプロイしてみた
Next.js(SSR)のアプリケーションを作成して、AWS にデプロイしてみたので、備忘録として残しておく。
- 0. ECR にイメージリポジトリを作成する
- 1. アプリをコマンドで実行できることを確認する
- 2. docker imageを作成する
- 3. ECRにdocker imageをpushする
- 4. Fargateクラスターを作成する
- 5. ALBのリスナーを「80」に設定する
- まとめ
今回の構成はこのようになっている。
バージョン情報は以下の通りである。
- aws
- docker
- Docker version 19.03.12, build 48a66213fe
0. ECR にイメージリポジトリを作成する
今回は、AWS Web Console でリポジトリを作成した。もちろん、AWS-CLI からも作成は可能である。
イメージリポジトリを作成後、イメージリポジトリのURI をメモして、控えておく。
1. アプリをコマンドで実行できることを確認する
開発時は、 yarn dev
で開発用のサーバーを起動して、開発を行っていたかと思う。本番は、yarn build
してから、yarn start
で本番環境で Nodeサーバーを起動する。
<--省略--> "scripts": { "dev": "nodemon", "build": "next build && tsc --project tsconfig.server.json", "start": "NODE_ENV=production node dist/index.js" }, <--省略-->
docker image を作成する前に、ローカル環境で、yarn build
と yarn start
が問題なく実行できることを確認する。実行して、エラーが出なければ、基本的には大丈夫である。
2. docker imageを作成する
Dockerfile
と .dockerignore
をアプリケーションディレクトリ直下に配置する。
app ┝ pages ┝ (省略) ┝ package.json ┝ .dockerignore ← ここに追加する └ Dockfile ← ここに追加する
Dockfile では Node 環境を用意し、必要なパッケージをインスール、ビルド後に、本番環境を起動するコマンドを実行している。(コンテナ内では、3000ポートで起動するように設定している。)
FROM node:14-alpine RUN mkdir -p /app COPY . /app WORKDIR /app RUN apk --update add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ apk del tzdata && \ apk add --no-cache bash RUN yarn install && \ yarn build ENV HOST 0.0.0.0 EXPOSE 3000 CMD ["yarn", "start"]
docker imageに含める必要のないファイルを .dockerignore に列挙しておく。
node_modules/ .next/ dist/
上記の Dockerfile と .dockerignore に従い、docker build
コマンドで docker image を作成する。(-t で、'名前:タグ' を設定する。)名前については、わかりやすいように私は、ECR で設定した<repositry-name>としている。
$ docker build -t <repositry-name>:latest .
build — Docker-docs-ja 17.06 ドキュメント
完成した docker image をローカル環境で実際に動作確認を行う。
// imageの確認 $ docker images // Dockerコンテナを起動する $ docker run -d -p 3000:3000 --name <repositry-name> <repositry-name>:latest
Docker run リファレンス — Docker-docs-ja 17.06 ドキュメント
http://localhost:3000 にアプリケーションが問題なく起動していれば、問題ない。
3. ECRにdocker imageをpushする
imageへのタグ付け(バージョニング)を行う。
$ docker tag <repositry-name>:latest <-repository URI ->/<repositry-name>:latest
ECRへのpush権限をdockerに与えるために AWS コマンドを実行する。AWS CLIの認証情報に関して、profile を用いている。profileに関しては、こちら を参考にしてください。
$ aws ecr get-login-password --profile <-profile name-> | docker login --username AWS --password-stdin <-repository URI ->/<repositry-name>:latest
image を ECR へ push する。
$ docker push <-repository URI ->/<repositry-name>:latest
4. Fargateクラスターを作成する
次に、AWS Web Console にて、ECS を選択して、クラスターを作成していく。
customを選択する。
- コンテナ名:任意に設定して問題ないが、私は ECR のリポジトリ名と同じで設定した。
- イメージ:ECR のリポジトリURI を設定する。
- ポートマッピング:「3000」とする。Dockerfile で 3000 ポートで設定しているので、ここが 3000 となる。
その他の設定は、今後すべきであるが、現段階ではとりあえず初期設定のままとした。
サービスを定義するでは、「ロードバランサーの種類」を「Application Load Balancer(ALB)」とする。ALB とせずに、自分で設定をしてもいいのであるが、ここで ALB を選択することで AWS 側で自動で様々な設定を行ってくれるので、今回は ALB を選択する。
クラスターの設定では、「クラスター名」を決定する。「コンテナ名-cluster」などで問題ないと思われる。
これで設定は完了である。
「作成実行」を行う。全てが完了になるまで、数分かかるので待機する。
5. ALBのリスナーを「80」に設定する
クラスター > 今回作成したクラスター > サービス を選択して、ロードバランシングのターゲットグループ名から、「EC2」の画面に移動する。
EC2 の ロードバランシング > ロードバランサー で DNS名などを確認することができる。
現時点では、DNS名:3000 ポートにアクセスすることで問題なく、アプリケーションを確認することができる。
ただし、毎回 3000 ポートを指定するのは面倒なので、「リスナー」タブより、外部に公開するポートは、「3000」ではなく、「80」に変更する。(SSH対応をする場合は、別途設定が必要である。)
まとめ
今回は、Next.js を AWS にデプロイした方法を整理した。
2020/07に、AWS と Docker のコラボレーションにより、Docker の ECSインテグレーションが発表されたので、今後は ECR に PUSH せずに、DockerHub に PUSH することも増えるかもしれない。この機能を試すのも、今後楽しみである。
それでは、ステキな開発ライフを。