Deployment

Build and deploy the Nuxt template to production.

The app builds to a Nitro .output bundle you can run on Node, in Docker, or on a platform like Vercel.

Quality gate

Run these before every deploy:

pnpm eslint .
pnpm build

pnpm build runs nuxt build and produces the Nitro .output directory.

Build outputs

CommandOutput
pnpm buildServer build in .output (run with node .output/server/index.mjs)
pnpm generateStatic site generation
pnpm previewServe the production build locally for a smoke test

Docker / self-hosting

The included Dockerfile is a two-stage node:22-alpine build: it installs with pnpm, runs pnpm build, and copies only .output into the runtime image. The container starts the Nitro server:

ENV PORT=80
ENV HOST=0.0.0.0
EXPOSE 80
CMD ["node", "/app/server/index.mjs"]

Pass every NUXT_* / NUXT_PUBLIC_* value as a runtime environment variable to the container.

Vercel

Nitro selects the Vercel preset automatically when you deploy on Vercel — no config change needed. @vercel/analytics is already wired in. Set the environment variables in the Vercel project settings.

Build vs runtime config

  • NUXT_PUBLIC_* values are exposed to the browser and are read into the client bundle.
  • NUXT_* server keys must be present in the runtime environment. Nitro reads runtimeConfig from matching NUXT_-prefixed env vars at runtime, so you can override values per environment without rebuilding.

Confirm NUXT_PUBLIC_AI_PUBLIC_DEMO is unset or false in production so the AI routes require login. Leaving it true exposes paid AI endpoints to anonymous traffic.

Pre-launch checklist

  • Production PostgreSQL provisioned and migrations applied (npx drizzle-kit migrate).
  • NUXT_PUBLIC_BASE_URL set to the real origin; stable NUXT_BETTER_AUTH_SECRET.
  • OAuth callback URLs point at the production domain.
  • Payment provider keys, webhook/notify URLs, Creem product IDs, and NUXT_CREEM_SERVER_IDX=0 configured.
  • Resend domain verified and sender/support addresses set.
  • site.url and SEO/OG metadata updated for the real domain.
  • AI keys set; NUXT_PUBLIC_AI_PUBLIC_DEMO is false.

Before exposing risky features

  • Uploads write to local public/uploads, which is not durable on serverless or replaceable containers — move to S3/R2/Blob first. See Storage.
  • AI routes enforce auth + Zod validation via requireAiAuth, but ship without quotas, moderation, or cost caps; rate limiting is intentionally out of scope. Add these before exposing the paid endpoints. See AI Chat.

Smoke test after deploy

  • Auth: register, verify, login, OAuth, reset.
  • Email: verification and contact messages deliver.
  • Payments: checkout and webhooks for each configured provider.
  • Dashboard and admin pages load with proper guards.
  • Content: docs/blog/legal render; English and /zh routes work.
  • AI chat and media (if enabled).
  • Image upload (if a durable backend is configured).

Also confirm DB backups, log/error reporting, and a secret-rotation plan.

On this page