C.W.K.
Stream
Lesson 05 of 08 · published

Environment Variables in Production

~20 min · env, build vs runtime, Docker

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Build-time vs runtime

Variable kindRead when?
NEXT_PUBLIC_*Build time — baked into the bundle
Server-onlyRuntime — read on every request

The Docker problem

Building one image and deploying it to staging + production with different settings? NEXT_PUBLIC_* values can't change between environments — they're already baked in. You either rebuild per environment or use runtime config strategies (e.g., proxy injects them, or you read from server only).

Loading order

  1. Already-set process.env
  2. .env.production.local / .env.development.local
  3. .env.local (skipped in test)
  4. .env.production / .env.development
  5. .env

Code

Force runtime read for an env var·tsx
import { connection } from 'next/server';

export default async function Page() {
  await connection(); // opt into per-request rendering
  const apiUrl = process.env.API_URL; // re-read each request
  return <div>API: {apiUrl}</div>;
}
Vercel CLI for environment scopes·bash
vercel env add DATABASE_URL production
vercel env add DATABASE_URL preview
vercel env add DATABASE_URL development

External links

Exercise

Build a Docker image with one set of NEXT_PUBLIC_* values. Deploy it to two environments and confirm the values match (i.e., they're baked in). Refactor one to be a server-only var and re-deploy.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.