Deploy Nuxt on AWS

Deploy your Nuxt applications to AWS using Thunder patterns. This guide covers both client-side rendering (CSR) deployment and full-stack server-side rendering options.

There are two deployment patterns available for Nuxt on AWS:

  1. Client-Side Rendering — Deploy client-side Nuxt sites using S3 and CloudFront with the Static construct
  2. Full Stack — Deploy SSR Nuxt applications using ECS Fargate with the Fargate construct

Client-Side Rendering Deployment


Deploy client-side Nuxt applications to S3 and CloudFront using the Static construct. This pattern is ideal for static sites, blogs, and client-side applications.

Create Project

Terminal window
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install

Configure Nuxt for Client-Side Rendering

nuxt.config.ts
export default defineNuxtConfig({
ssr: false,
})

Install Dependencies and Setup Stack

Terminal window
npm i tsx @thunder-so/thunder --save-dev
stack/index.ts
import { 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: '.output/public',
};
new Static(
new Cdk.App(),
`${myApp.application}-${myApp.service}-${myApp.environment}-stack`,
myApp
);

Deploy

Build and deploy your Nuxt SPA:

Terminal window
npm run build
npx cdk deploy --all --app="npx tsx stack/index.ts"

After deployment, you’ll receive a CloudFront URL to access your application.

Full Stack Deployment


Deploy server-side rendered Nuxt applications using ECS Fargate and Application Load Balancer with the Fargate construct.

Configure Nuxt for SSR

nuxt.config.ts
export default defineNuxtConfig({
ssr: true,
})

Install Dependencies and Setup Stack

Terminal window
npm i tsx @thunder-so/thunder --save-dev
stack/index.ts
import { 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:

stack/index.ts
const svcProps: FargateProps = {
// ... other props
buildProps: {
buildSystem: 'Nixpacks',
installcmd: 'bun install',
buildcmd: 'bun run build',
startcmd: 'bun start',
},
};

Build Settings Using Docker Container

Alternatively, use a custom Dockerfile:

Dockerfile
FROM public.ecr.aws/docker/library/node:20-alpine AS base
FROM base AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.output ./.output
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]
stack/index.ts
const svcProps: FargateProps = {
// ... other props
serviceProps: {
dockerFile: 'Dockerfile',
port: 3000,
},
};

Environment Variables and Secrets for SSR

Configure runtime environment variables and secrets:

stack/index.ts
const svcProps: FargateProps = {
// ... other props
serviceProps: {
variables: [
{ NODE_ENV: 'production' },
{ NUXT_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:

Terminal window
npm run build
npx cdk deploy --all --app="npx tsx stack/index.ts"

After deployment, you’ll receive an Application Load Balancer URL to access your SSR application.