Deploy Next.js on AWS with Thunder
Deploy your Next.js applications to AWS using Thunder patterns. This guide covers both static export deployment and full-stack server-side rendering options.
There are two deployment patterns available for Next.js on AWS:
- Static Export (SPA) — Deploy static Next.js sites using S3 and CloudFront with the
Staticconstruct - Full Stack — Deploy SSR Next.js applications using ECS Fargate with the
Fargateconstruct
Static Export (SPA) Deployment
Deploy Next.js static export applications to S3 and CloudFront using the Static construct. This pattern is ideal for static sites, blogs, and client-side applications.
Create Project
npm create next-app@latest my-nextjs-appcd my-nextjs-apppnpm create next-app my-nextjs-appcd my-nextjs-appbun create next-app my-nextjs-appcd my-nextjs-appConfigure Next.js for Static Export
import type { NextConfig } from "next";
const nextConfig: NextConfig = { output: "export", // Enable static export};
export default nextConfig;In your tsconfig.json, ensure the stack directory is excluded:
{ "compilerOptions": { // ... other options }, "exclude": ["node_modules", "stack"]}Install Dependencies and Setup Stack
npm i tsx @thunder-so/thunder --save-devpnpm add -D tsx @thunder-so/thunderbun add -d tsx @thunder-so/thunderimport { Cdk, Static, type StaticProps } from "@thunder-so/thunder";
const myApp: StaticProps = { env: { account: 'your-account-id', region: 'us-east-1' }, application: 'your-application-id', service: 'your-service-id', environment: 'production',
rootDir: '', // e.g. 'frontend' for monorepos outputDir: 'out',};
new Static( new Cdk.App(), `${myApp.application}-${myApp.service}-${myApp.environment}-stack`, myApp);Deploy
Build and deploy your static site:
npm run buildnpx cdk deploy --all --app="npx tsx stack/index.ts"pnpm run buildpnpm exec cdk deploy --all --app="pnpm exec tsx stack/index.ts"bun run buildnpx cdk deploy --all --app="bunx tsx stack/index.ts"After deployment, you’ll receive a CloudFront URL to access your static site.
Full Stack Deployment
Deploy server-side rendered Next.js applications using ECS Fargate and Application Load Balancer with the Fargate construct.
Configure Next.js for SSR
import type { NextConfig } from "next";
const nextConfig: NextConfig = { // Next.js defaults to SSR, no configuration needed};
export default nextConfig;Install Dependencies and Setup Stack
npm i tsx @thunder-so/thunder --save-devpnpm add -D tsx @thunder-so/thunderbun add -d tsx @thunder-so/thunderimport { Cdk, Fargate, type FargateProps } from "@thunder-so/thunder";
const svcProps: FargateProps = { env: { account: 'your-account-id', region: 'us-west-2' }, application: 'your-application-id', service: 'your-service-id', environment: 'production',
rootDir: '', // e.g. 'app' for monorepos};
new Fargate( new Cdk.App(), `${svcProps.application}-${svcProps.service}-${svcProps.environment}-stack`, svcProps);Build Settings Using Nixpacks
Configure automatic containerization with Nixpacks:
const svcProps: FargateProps = { // ... other props
buildProps: { buildSystem: 'Nixpacks', installcmd: 'npm install', buildcmd: 'npm run build', startcmd: 'npm start', },};Build Settings Using Docker Container
Alternatively, use a custom Dockerfile:
FROM public.ecr.aws/docker/library/node:20-alpine AS base
FROM base AS builderWORKDIR /app
COPY package*.json ./RUN npm ci
COPY . .RUN npm run build
FROM base AS runnerWORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]const svcProps: FargateProps = { // ... other props
serviceProps: { dockerFile: 'Dockerfile', port: 3000, },};Environment Variables and Secrets for SSR
Configure runtime environment variables and secrets:
const svcProps: FargateProps = { // ... other props
serviceProps: { variables: [ { NODE_ENV: 'production' }, { NEXT_PUBLIC_API_URL: 'https://api.example.com' } ], secrets: [ { key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-west-2:123456789012:secret:/my-app/DATABASE_URL-abc123' }, ], },};Deploy
Build and deploy your containerized application:
npm run buildnpx cdk deploy --all --app="npx tsx stack/index.ts"pnpm run buildpnpm exec cdk deploy --all --app="pnpm exec tsx stack/index.ts"bun run buildnpx cdk deploy --all --app="bunx tsx stack/index.ts"After deployment, you’ll receive an Application Load Balancer URL to access your SSR application.