The coexistence model, page-by-page migration strategy, getServerSideProps→RSC, getStaticProps→generateStaticParams, API Routes→Route Handlers, next/router→next/navigation API differences, _app/_document→RootLayout providers, Middleware behaviour during partial migration, and the ten pitfalls that block every team mid-migration.
P-14 — Deployment and CI/CD Pipelines
Who this is for: Practitioners ready to ship. You've built the application — now you need to understand where it can run, what the trade-offs are between deployment targets, and how to build a CI/CD pipeline that catches problems before they reach users. This module covers the full deployment matrix: Vercel, self-hosted Node.js, Docker, and static export.
Three Deployment Targets
Every Next.js application can be deployed in three fundamentally different ways, and the choice affects which features work:
Vercel — zero-configuration, all features supported, preview deployments per PR, built-in ISR/PPR/edge compute. The path of least resistance and the right choice for most applications.
Self-hosted Node.js (standalone output) — full Next.js feature support (ISR, streaming, Server Actions, Route Handlers), requires a persistent Node.js process or container orchestration, more operational overhead.
Static export — pure HTML/CSS/JS files served from any CDN. No server required, no ISR, no Route Handlers that use Node.js APIs, no dynamic routes without workarounds. The right choice when you genuinely need zero server dependency.
The decision is not about preference — it's about which features your application uses.
Vercel Deployment
Vercel is the path with the least distance between code and production. Push to your main branch, it deploys. No configuration required for a Next.js application — Vercel detects it automatically and configures the build correctly.
Environment variables per environment:
The Vercel CLI lets you pull remote env vars into a local .env.local:
Preview deployments are the feature that pays for itself in minutes. Every pull request gets its own live URL — https://my-app-git-feature-branch-team.vercel.app. Your team reviews real running code, not static screenshots. Preview deployments use the Preview environment variables, so they can point at a staging database.
Zero-downtime deploys are automatic on Vercel. The old version continues serving traffic until the new deployment is ready. Instant rollback to any previous deployment via the dashboard or CLI:
Standalone Output — Self-Hosting
For self-hosted deployments, enable standalone output in next.config.ts:
After npm run build, Next.js generates .next/standalone — a minimal self-contained directory with only the Node.js server and its actual runtime dependencies (no node_modules bloat from dev dependencies or unused packages). Typical size reduction: from 500MB to 40–80MB.
The standalone server runs with:
You need to copy two additional directories alongside the standalone output — Next.js doesn't include them automatically:
Docker Multi-Stage Build
The canonical Dockerfile for a standalone Next.js application:
Key details:
- Three stages keep the final image small — the builder stage has all dev tools, the runner has only what's needed at runtime.
- Non-root user is a security requirement for most container security policies. The
nextjsuser owns the.nextdirectory so ISR can write revalidated pages. NEXT_PUBLIC_*vars at build time — these are baked into the JavaScript bundle during build, not read at runtime. Pass them as build args.- Server-side env vars at runtime —
DATABASE_URL,AUTH_SECRET, and other server-only vars are injected at container run time via-eor an env file, not baked into the image.
Static Export
For applications with no server-side requirements:
npm run build generates an out/ directory of plain HTML files. Deploy it to any static host: S3 + CloudFront, Cloudflare Pages, Netlify, GitHub Pages.
Hard constraints with static export:
- No ISR (no server to revalidate)
- No Route Handlers that use Node.js APIs or dynamic request data
- No Middleware
- No
cookies()orheaders()in Server Components - Image optimization needs a custom loader (Cloudinary, imgix, or
unoptimized: true) - All dynamic routes must have
generateStaticParams
Static export is the right choice for marketing sites, documentation, and any application where the content is fully known at build time and a CDN is sufficient.
Environment Variable Validation at Build Time
Deploy with a missing DATABASE_URL and you get a runtime crash. Validate at build time instead:
Import serverEnv from any Server Component or Route Handler. The build fails immediately with a descriptive Zod error if a required variable is absent — much better than discovering the missing variable at runtime after deploy.
GitHub Actions CI Pipeline
Deploy to Vercel on merge to main:
Health Check Endpoint
Every deployed application needs a health check endpoint — for load balancers, Kubernetes liveness probes, and uptime monitors:
Return 200 when healthy, 503 when degraded. Load balancers stop routing to instances that return 503 — this is how you get automatic failover when a database connection fails.
Where We Go From Here
The Practitioner phase is complete. You can build, authenticate, cache, test, configure, and deploy production Next.js applications. The Architect phase begins with A-1 — the RSC internals that explain why the framework behaves the way it does at the protocol level. Understanding the React Flight wire format is what separates engineers who debug Next.js confidently from engineers who guess.
Which deployment target is required if your application relies heavily on Incremental Static Regeneration (ISR) but you cannot use Vercel?
When building a Docker image for a standalone Next.js application, how should public environment variables (NEXT_PUBLIC_*) be handled?
What is a hard constraint of using the static export (output: 'export') in Next.js?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
Sign in & RegisterDiscussion
0Join the discussion