You have built pages, layouts, data fetching and API routes. The final step is shipping your Next.js application to real users. In this lesson you will learn how a production build works, the main deployment options from Vercel to self-hosting with Node.js and Docker, which environment variable rules to follow, and a checklist of best practices that keep production apps fast and stable.
Everything starts with the build command. It compiles your code, prerenders static routes, and outputs an optimized bundle in the .next directory:
npm run build # runs next build
npm run start # runs next start, serving the production buildThe build output lists every route and how it will be served: static routes are prerendered at build time, while dynamic ones are rendered on demand on the server. Reviewing this table is the fastest way to confirm your caching strategy is what you intended. Always run the production build locally before deploying; it surfaces type errors, missing environment variables and oversized bundles that the dev server tolerates.
Vercel, the company behind Next.js, offers the most frictionless path. Push your repository to GitHub, import the project on vercel.com, and every push to your main branch triggers a build and deployment. Pull requests get their own preview URLs, which is excellent for review workflows. Server Components, route handlers, streaming and image optimization all work with zero configuration, and a global CDN serves your static assets automatically.
You are not locked into any platform. A Next.js app is a Node.js server, so any VPS or container platform works. The standalone output mode produces a minimal server folder that is ideal for Docker:
// next.config.js
module.exports = {
output: 'standalone',
};FROM node:20-alpine
WORKDIR /app
COPY .next/standalone ./
COPY .next/static ./.next/static
COPY public ./public
EXPOSE 3000
CMD ["node", "server.js"]Behind the container, put a reverse proxy such as Nginx for TLS termination and compression. If your app is fully static, next build with output: 'export' can emit plain HTML files servable from any static host, at the cost of server features.
Next.js reads variables from the hosting platform or from .env files. Two rules matter. First, only variables prefixed with NEXT_PUBLIC_ are exposed to the browser; everything else stays server-only, so keep API secrets unprefixed. Second, values are inlined at build time for client code, so changing a NEXT_PUBLIC_ variable requires a rebuild, not just a restart.
DATABASE_URL=postgres://... # server-only secret
NEXT_PUBLIC_ANALYTICS_ID=abc123 # safe for the browserA short checklist that pays off on every project. Keep most components as Server Components and push 'use client' to the leaves of the tree to minimize JavaScript sent to the browser. Use the built-in Image and Font optimization you learned earlier. Choose caching deliberately: static rendering where content allows, revalidation intervals for content that changes occasionally, and dynamic rendering only where truly necessary. Add a global error boundary with error.tsx and a custom not-found page. Monitor Core Web Vitals after launch, and run npx next build with the bundle analyzer occasionally to catch dependency bloat before users feel it.
That wraps up the Next.js course. As a next step, explore our Linux Command Line course to get comfortable managing the servers your applications run on.