初めに
本プロジェクトはchatGPTと対話しながら進めました
nextjsをwebに公開する一連の流れを記録した備忘録になります
これ以降は対話した内容をchatGPTにまとめてもらったものです
大分つたないものなので要望があればちゃんと書きます
1. Next.js プロジェクトを作成し、GitHub にプッシュ
まず、Next.js のプロジェクトを作成し、それを GitHub にプッシュします。
1.1 Next.js プロジェクトの作成
npx create-next-app my-app
cd my-app
1.2 GitHub リポジトリの作成とプッシュ
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/next_test.git
git push -u origin main
2. Terraform を使用して AWS 環境を構築
Terraform を使って AWS のインフラをコード化し、ECS 上で Next.js を動かす環境を作ります。
2.1 AWS CLI の設定
AWS の CLI をインストールし、認証情報を設定します。
aws configure
2.2 ネットワークの構築 (network.tf
)
ECS を動作させるための VPC、サブネット、NAT ゲートウェイを設定します。
VPC の作成
resource "aws_vpc" "my_app_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "my-app-vpc" }
}
パブリック / プライベートサブネットの作成
resource "aws_subnet" "my_app_subnets" {
count = 2
vpc_id = aws_vpc.my_app_vpc.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = element(["ap-northeast-1a", "ap-northeast-1c"], count.index)
map_public_ip_on_launch = count.index == 0 ? true : false
tags = { Name = "my-app-subnet-${count.index}" }
}
NAT ゲートウェイの作成
resource "aws_eip" "my_app_nat_eip" { domain = "vpc" }
resource "aws_nat_gateway" "my_app_nat_gw" {
allocation_id = aws_eip.my_app_nat_eip.id
subnet_id = aws_subnet.my_app_subnets[0].id
}
ルートテーブルの設定
resource "aws_route_table" "my_app_private_rt" {
vpc_id = aws_vpc.my_app_vpc.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.my_app_nat_gw.id
}
}
2.3 ECS クラスターの作成 (ecs.tf
)
resource "aws_ecs_cluster" "my_app_ecs_cluster" {
name = "my-app-ecs-cluster"
}
2.4 ALB の設定 (alb.tf
)
resource "aws_lb" "my_app_alb" {
name = "my-app-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.my_app_sg.id]
subnets = aws_subnet.my_app_subnets[*].id
}
3. CodePipeline を使用してビルドとデプロイを自動化
GitHub の変更をトリガーに、ECR にコンテナをプッシュし、ECS にデプロイされるようにします。
3.1 CodePipeline の設定 (codepipeline.tf
)
resource "aws_codepipeline" "my_app_codepipeline" {
name = "my-app-codepipeline"
role_arn = aws_iam_role.my_app_codepipeline_role.arn
artifact_store {
location = aws_s3_bucket.my_app_pipeline_artifacts.bucket
type = "S3"
}
}
3.2 CodeBuild の buildspec.yml
ECR へのビルドとプッシュ、ECS の更新を行います。
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPOSITORY
build:
commands:
- docker build -t my-app .
- docker tag my-app:latest $ECR_REPOSITORY:latest
post_build:
commands:
- docker push $ECR_REPOSITORY:latest
- aws ecs update-service --cluster my-app-ecs-cluster --service my-app-service --force-new-deployment
4. デプロイの確認
ALB の URL にアクセスし、Next.js の画面が表示されることを確認します。
aws ecs describe-services --cluster my-app-ecs-cluster --services my-app-service --query 'services[*].loadBalancers[*].{DNSName:dnsName}' --output table
5. トラブルシューティングと学び
このプロジェクトを進める中で、いくつかの大きな課題に直面しました。
5.1 403 Forbidden エラー (ECR のプル失敗)
ECS が ECR からイメージを取得しようとした際に 403 Forbidden
が発生。
原因: NAT ゲートウェイの未設定により、プライベートサブネットのタスクが ECR にアクセスできなかった。
解決策:
- NAT ゲートウェイを追加し、適切なルートテーブル設定を行うことで、ECS タスクが ECR へアクセスできるように修正。
5.2 ALB のターゲットグループのヘルスチェックが失敗 (502 Bad Gateway)
ALB から ECS のタスクにリクエストを送った際に 502 Bad Gateway
が発生。
原因:
- タスク定義で
containerPort
の設定が不足していた。 - Next.js のアプリが
0.0.0.0
ではなくlocalhost
で起動されていた。
解決策:
- ECS タスク定義に
containerPort: 80
を追加。 -
next.config.js
を修正し、適切なポートバインドを行う。
まとめ
AWS ECS Fargate に Next.js アプリケーションを Terraform を使ってデプロイすることができました! 🎉
次のステップとして、
- CodeDeploy を組み込んでブルーグリーンデプロイを試す
- CloudWatch Logs の統合を強化する
- ALB のヘルスチェック設定を最適化する
を試すと、より安定した運用ができるようになります! 🚀