Deployment

Deploy your Nuxt application to production

This guide covers deploying your Nuxt 4 application to various hosting platforms.

Pre-deployment checklist

Before deploying to production:

  • Set all required environment variables.
  • Use production API keys (Stripe live keys, etc.).
  • Configure production database.
  • Set up Stripe webhooks for production URL.
  • Test the application thoroughly.
  • Set up error monitoring (Sentry, etc.).
  • Configure analytics (Umami and/or Vercel Analytics).
  • Review security settings.
  • Set up SSL certificate.

Vercel provides the best experience for Nuxt applications with zero configuration.

Deployment steps

  1. Push to Git:
git push origin main
  1. Import project in Vercel:
    • Go to vercel.com.
    • Click "Add New Project".
    • Import your Git repository.
    • Vercel auto-detects Nuxt and configures build settings.
  2. Configure environment variables:
    • In project settings → Environment Variables.
    • Add all variables from your .env file.
    • Set appropriate scope (Production/Preview/Development).
  3. Deploy:
    • Vercel automatically deploys on every push.
    • View deployment at your .vercel.app domain.

Custom domain

  1. Go to project settings → Domains.
  2. Add your custom domain.
  3. Configure DNS records as instructed.
  4. SSL is automatically provisioned.

Build settings

Vercel uses these defaults (no configuration needed):

{
  "buildCommand": "pnpm build",
  "outputDirectory": ".output/public",
  "installCommand": "pnpm install"
}

Netlify

Deployment steps

  1. Create netlify.toml:
netlify.toml
[build]
  publish = ".output/public"
  command = "pnpm build"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

[context.production.environment]
  NUXT_PUBLIC_SITE_URL = "https://yourdomain.com"
  1. Connect to Netlify:
    • Go to netlify.com.
    • Import your Git repository.
    • Configure build settings.
    • Add environment variables.
  2. Deploy:
    • Automatic deployment on Git push.

Cloudflare Pages

Deployment steps

  1. Connect repository:
    • Go to Cloudflare dashboard.
    • Create new Pages project.
    • Connect Git repository.
  2. Build configuration:
    • Framework preset: Nuxt.js.
    • Build command: pnpm build.
    • Build output directory: .output/public.
  3. Environment variables:
    • Add in project settings.
    • Use separate variables for production/preview.
  4. Deploy:
    • Automatic deployment on push.

Docker

Dockerfile

Dockerfile
# Build stage
FROM node:20-alpine AS build

WORKDIR /app

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# Copy package files
COPY package.json pnpm-lock.yaml ./

# Install dependencies
RUN pnpm install --frozen-lockfile

# Copy source code
COPY . .

# Build application
RUN pnpm build

# Production stage
FROM node:20-alpine

WORKDIR /app

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# Copy built application
COPY --from=build /app/.output ./.output
COPY --from=build /app/package.json ./

# Expose port
EXPOSE 3000

# Set environment
ENV NODE_ENV=production
ENV PORT=3000

# Start application
CMD ["node", ".output/server/index.mjs"]

docker-compose.yml

docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - '3000:3000'
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - NUXT_PUBLIC_SITE_URL=${NUXT_PUBLIC_SITE_URL}
      - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:

Build and run

# Build image
docker build -t myapp .

# Run container
docker run -p 3000:3000 \
  -e DATABASE_URL="..." \
  -e STRIPE_SECRET_KEY="..." \
  myapp

# Or use docker-compose
docker-compose up -d

DigitalOcean App Platform

Deployment steps

  1. Create app:
    • Go to DigitalOcean dashboard.
    • Create App Platform app.
    • Connect Git repository.
  2. Configure build:
    • Build command: pnpm build.
    • Run command: node .output/server/index.mjs.
  3. Add environment variables:
    • In app settings.
    • Include all required variables.
  4. Add database (optional):
    • Add PostgreSQL database component.
    • Connection string auto-set in DATABASE_URL.

AWS (EC2)

Deployment steps

  1. Launch EC2 instance:
    • Ubuntu 22.04 LTS.
    • t3.small or larger.
    • Configure security group (allow HTTP/HTTPS).
  2. Install dependencies:
# Connect to instance
ssh ubuntu@your-instance-ip

# Update system
sudo apt update && sudo apt upgrade -y

# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Install pnpm
npm install -g pnpm

# Install PM2
npm install -g pm2
  1. Deploy application:
# Clone repository
git clone https://github.com/youruser/yourrepo.git
cd yourrepo

# Install dependencies
pnpm install

# Build application
pnpm build

# Start with PM2
pm2 start .output/server/index.mjs --name myapp

# Save PM2 configuration
pm2 save
pm2 startup
  1. Configure Nginx reverse proxy:
# /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
# Enable site
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

# Install SSL with Certbot
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com

Environment-specific configurations

Production

.env.production
NODE_ENV=production
NUXT_PUBLIC_SITE_URL="https://yourdomain.com"
DATABASE_URL="postgresql://prod-db:5432/myapp"
STRIPE_SECRET_KEY="sk_live_..."
STRIPE_WEBHOOK_SECRET="whsec_..."

# Analytics (optional)
NUXT_PUBLIC_UMAMI_ID="prod-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://analytics.yourdomain.com"
NUXT_PUBLIC_VERCEL_ANALYTICS="true"

Staging

.env.staging
NODE_ENV=staging
NUXT_PUBLIC_SITE_URL="https://staging.yourdomain.com"
DATABASE_URL="postgresql://staging-db:5432/myapp_staging"
STRIPE_SECRET_KEY="sk_test_..."

# Analytics (optional)
NUXT_PUBLIC_UMAMI_ID="staging-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://analytics.yourdomain.com"

Database migrations

Run Prisma migrations in production:

# In your CI/CD pipeline or deployment script
pnpm prisma migrate deploy
Never use prisma migrate dev in production. Use migrate deploy instead.

Health checks

Add a health check endpoint:

server/api/health.ts
export default defineEventHandler(async () => {
  // Check database connection
  try {
    await prisma.$queryRaw`SELECT 1`
    return {
      status: 'healthy',
      timestamp: new Date().toISOString(),
    }
  } catch (error) {
    throw createError({
      statusCode: 503,
      message: 'Service unavailable',
    })
  }
})

Use in your monitoring:

curl https://yourdomain.com/api/health

Monitoring and logging

Error tracking (Sentry)

pnpm add @sentry/nuxt
nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@sentry/nuxt/module'],
  sentry: {
    dsn: process.env.SENTRY_DSN,
  },
})

Application monitoring

  • Umami Analytics: Privacy-focused web analytics (self-hosted or cloud).
  • Vercel Analytics: Real-time traffic insights and Web Vitals.
  • Datadog: Full-stack monitoring.
  • New Relic: APM and monitoring.
  • LogRocket: Session replay and monitoring.
See the analytics integration guide for Umami and Vercel Analytics setup.

Performance optimization

Enable caching

nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    compressPublicAssets: true,
    routeRules: {
      '/': { prerender: true },
      '/api/**': { cors: true, headers: { 'cache-control': 's-maxage=60' } },
    },
  },
})

Image optimization

Use @nuxt/image for automatic optimization:

<NuxtImg src="/image.jpg" loading="lazy" format="webp" quality="80" />

Code splitting

Nuxt automatically code-splits by route. For large components:

<script setup>
const HeavyComponent = defineAsyncComponent(() => import('./HeavyComponent.vue'))
</script>

CI/CD

GitHub Actions

.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v2
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

      - name: Build
        run: pnpm build
        env:
          NUXT_PUBLIC_SITE_URL: ${{ secrets.SITE_URL }}

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}

Troubleshooting

Build failures

Check Node.js version:

node --version  # Should be 20.x or higher

Clear cache:

rm -rf .nuxt .output node_modules
pnpm install
pnpm build

Runtime errors

Check logs:

  • Vercel: View in deployment logs.
  • Docker: docker logs container-name.
  • PM2: pm2 logs myapp.

Check environment variables:

# Verify variables are set
env | grep NUXT_

Database connection errors

  • Verify DATABASE_URL is correct.
  • Check database is accessible from deployment.
  • Verify SSL mode if required.
  • Check firewall rules.

Post-deployment

After successful deployment:

  1. Test the application:
    • Test all critical flows.
    • Test authentication.
    • Test payments (with test mode first).
  2. Configure monitoring:
    • Set up error alerts.
    • Configure uptime monitoring.
    • Set up performance monitoring.
  3. Set up backups:
    • Database backups.
    • File storage backups.
  4. Documentation:
    • Document deployment process.
    • Document rollback procedure.
    • Document emergency contacts.

Reference

Start with Vercel for the easiest deployment experience. You can always migrate to other platforms later if needed.