Topic 17 of 47
Deployment & Production
Overview
Deploying Next.js correctly ensures optimal performance. Vercel is the native platform (created by Next.js team), but Docker, AWS, and standalone output also work. Understanding build output and runtime requirements prevents deployment issues.
Syntax
dockerfile
// next.config.ts for different deployment targets
// Standalone output (Docker/self-hosted)
const config = {
output: "standalone", // minimal self-contained build
};
// Static export (no server needed)
const config = {
output: "export", // only works if no dynamic routes/server features
};
// package.json scripts
{
"scripts": {
"dev": "next dev",
"build": "next build", // creates .next/ folder
"start": "next start", // starts production server
"lint": "next lint"
}
}
// Dockerfile (standalone)
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
CMD ["node", "server.js"]Common Pitfalls
- Edge runtime doesn't support Node.js APIs (fs, crypto, buffers) — check runtime compatibility before using edge routes.
- Static export (output: 'export') doesn't support Server Components with dynamic data or API routes.
- Interview tip: Vercel's zero-config deployment is ideal for Next.js. For enterprise, standalone output with Docker gives full control over the runtime environment.
Real-World Example
Production checklist for a Next.js deployment
example
dockerfile
// 1. Environment variables in production (Vercel)
// Set via Vercel dashboard or CLI:
// vercel env add DATABASE_URL production
// 2. Database migrations before deploy
// package.json
{
"scripts": {
"build": "prisma generate && prisma migrate deploy && next build"
}
}
// 3. Health check endpoint
// app/api/health/route.ts
export async function GET() {
try {
await db.$queryRaw`SELECT 1`; // check DB connection
return Response.json({ status: "ok", timestamp: new Date().toISOString() });
} catch {
return Response.json({ status: "error" }, { status: 503 });
}
}
// 4. Error monitoring (Sentry)
// next.config.ts
import { withSentryConfig } from "@sentry/nextjs";
export default withSentryConfig(config, { silent: true });