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 buildpnpm build runs nuxt build and produces the Nitro .output directory.
Build outputs
| Command | Output |
|---|---|
pnpm build | Server build in .output (run with node .output/server/index.mjs) |
pnpm generate | Static site generation |
pnpm preview | Serve 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 readsruntimeConfigfrom matchingNUXT_-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_URLset to the real origin; stableNUXT_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=0configured. - Resend domain verified and sender/support addresses set.
-
site.urland SEO/OG metadata updated for the real domain. - AI keys set;
NUXT_PUBLIC_AI_PUBLIC_DEMOisfalse.
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
/zhroutes 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.
