AWSマネジメントコンソールでVPCを作成します。「VPCなどを作成」ウィザードを使用すると、Public Subnet、Private Subnet、ルートテーブル、インターネットゲートウェイ、NATゲートウェイを一度に作成できて便利です。
my-nextjs-vpc
)10.0.0.0/16
com.amazonaws.region.ecr.api
、com.amazonaws.region.ecr.dkr
、com.amazonaws.region.logs
のインターフェイスエンドポイントを作成することを推奨します(特にNATゲートウェイを使用しない場合やコストを抑えたい場合)。my-alb-sg
Security group for Application Load Balancer
HTTP
TCP
80
任意の場所IPv4 (0.0.0.0/0)
または、テスト用に特定のIPアドレス/範囲を指定します。
Allow HTTP access from anywhere
sg-xxxxxxxx
)を控えておきます。my-ecs-sg
Security group for ECS tasks
カスタムTCP
TCP
3000
(Next.jsアプリケーションがリッスンするポートに合わせてください)my-alb-sg
のID)を入力または選択します。Allow access from ALB on port 3000
my-nextjs-cluster
プライベート
my-nextjs-app
無効
または 有効
(推奨は 有効
ですが、開発中は 無効
の方が便利かもしれません)有効
にすることを推奨します。アカウントID.dkr.ecr.リージョン.amazonaws.com/my-nextjs-app
)を控えておきます。既存のNext.jsアプリケーションがある場合はそれを使用します。ない場合は、簡単なアプリケーションを作成します。
npx create-next-app@latest my-nextjs-app
cd my-nextjs-app
プロジェクトのルートディレクトリに Dockerfile
という名前のファイルを作成し、以下の内容を記述します。
node:18-alpine
のバージョンは、お使いのNext.jsやNode.jsのバージョンに合わせて調整してください。
Next.jsのStandalone Output機能を利用すると、より軽量なイメージを作成できます。その場合はDockerfileの内容が変わります。
FROM node:18-alpine AS alpine FROM alpine AS base FROM base AS builder COPY package.json package-lock.json ./ RUN npm install WORKDIR /app COPY . . RUN npm run build # Add lockfile and package.json's of isolated subworkspace FROM base AS installer WORKDIR /app FROM alpine AS runner WORKDIR /app # Don't run production as root RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs USER nextjs # Automatically leverage output traces to reduce image size # https://nextjs.org/docs/advanced-features/ output-file-tracing COPY --from=builder --chown=nextjs:nodejs /app/.next/ standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/ static ./.next/static COPY --from=builder --chown=nextjs:nodejs /app/public ./ public CMD ["node", "server.js"]
この場合、next.config.js
に以下を追加する必要があります。
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfig
AWS CLIでECRにログインします。
ターミナルで以下のコマンドを実行します。アカウントID
とリージョン
はご自身のものに置き換えてください。
aws ecr get-login-password --region リージョン | docker login --username AWS --password-stdin アカウントID.dkr.ecr.リージョン.amazonaws.com
成功すると "Login Succeeded" と表示されます。
Dockerイメージをビルドします。
Dockerfile
があるディレクトリで以下のコマンドを実行します。リポジトリURI
はステップ4で控えたものです。
docker build -t リポジトリURI:latest .
例: docker build -t アカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/my-nextjs-app:latest .
DockerイメージをECRにプッシュします。
docker push リポジトリURI:latest
例: docker push アカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/my-nextjs-app:latest
my-nextjs-task
awsvpc
(Fargateでは必須)AmazonECSTaskExecutionRolePolicy
) がアタッチされたロールが作成されます。Linux
0.5 vCPU
1 GB
my-nextjs-container
アカウントID.dkr.ecr.リージョン.amazonaws.com/my-nextjs-app:latest
)を入力します。3000
(DockerfileでEXPOSEしたポート、Next.jsがリッスンするポート)tcp
awsvpc
モードでは指定不要です。HTTP
(ALBがgRPCなど特定のプロトコルを想定しない場合)NODE_ENV=production
, PORT=3000
など)。
PORT=3000
はDockerfileやNext.jsの起動コマンドで指定されていれば不要です。/ecs/my-nextjs-task
ecs
my-nextjs-cluster
)をクリックします。FARGATE
LATEST
を選択します。サービス
my-nextjs-task
)を選択します。latest
または特定のリビジョンを選択します。my-nextjs-service
レプリカ
2
で高可用性を確保)。50
200
my-ecs-sg
)を選択します。無効
(ALB経由でアクセスするため)。Application Load Balancer
を選択します。my-nextjs-alb
my-nextjs-container:3000:tcp
)を選択します。HTTP
80
my-nextjs-tg
IPアドレス
(Fargateの場合)HTTP
/
(またはアプリケーションのルートパス)/api/health
など。なければ /
でも可)HTTP
トラフィックポート
、間隔、タイムアウトなど)を適切に設定します。AmazonECSTaskExecutionRolePolicy
がアタッチされているか確認します。このポリシーにはECRからのイメージプル権限 (ecr:GetAuthorizationToken
, ecr:BatchCheckLayerAvailability
, ecr:GetDownloadUrlForLayer
, ecr:BatchGetImage
) が含まれています。com.amazonaws.region.ecr.api
, com.amazonaws.region.ecr.dkr
) を作成し、VPC内のプライベートサブネットに関連付けます。これにより、トラフィックはAWSネットワーク内で完結し、NATゲートウェイが不要になる場合があります(ECRアクセスに関してのみ)。com.amazonaws.region.logs
) も同様に設定すると、ログ送信もプライベート接続になります。EC2サービスのナビゲーションペインから「ロードバランサー」を選択します。
ステップ8で作成されたALB(例: my-nextjs-alb
)を選択します。
「説明」タブにある「DNS名」(例: my-nextjs-alb-xxxxxxxxxx.リージョン.elb.amazonaws.com
)をコピーします。
WebブラウザのアドレスバーにこのDNS名を貼り付けてアクセスし、Next.jsアプリケーションが表示されることを確認します。
my-alb-sg
)のインバウンドルールでHTTP (80) が許可されているか。my-ecs-sg
)のインバウンドルールでALBのセキュリティグループからのTCP (3000) が許可されているか。