Fix environment variables missing at build time on Coolify

Error: Build-time error: process.env.NEXT_PUBLIC_* / VITE_* / API URL is undefined during build — values set in Coolify are empty in the built bundle (e.g. ReferenceError or fetch to "undefined")

Variables you set in Coolify exist at runtime but weren't injected during the image build, so anything baked in at build (NEXT_PUBLIC_*, VITE_*, REACT_APP_*) comes out empty.

Coolify scopes every variable independently for Build and Runtime, each with its own checkbox (both ON by default). If a variable's Build Variable checkbox is OFF, the value is not passed as a Docker --build-arg, so framework variables that are inlined into the bundle at build time (NEXT_PUBLIC_*, VITE_*, REACT_APP_*) compile to undefined even though they read fine at runtime. For Dockerfile build packs there is a second trap: Docker only exposes a --build-arg to a RUN step if a matching ARG is declared in the Dockerfile, so an undeclared build variable is silently dropped.

The fix

  1. In Coolify open the app's Environment Variables in Normal view, find each variable the build needs, and make sure its Build Variable checkbox is ON. Save. (Both Build and Runtime are ON by default for new variables, but check existing ones.)

    NEXT_PUBLIC_API_URL=https://api.your-domain.com   # Build Variable = ON
  2. For Dockerfile build packs, declare a matching ARG in the Dockerfile before you use it, then promote it to ENV so the build step can read it. Without the ARG line Docker drops the --build-arg value.

    ARG NEXT_PUBLIC_API_URL
    ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
    RUN npm run build
  3. Multi-stage Dockerfile gotcha: an ARG declared before FROM goes out of scope after FROM. Re-declare the ARG inside the stage that runs the build, or the value will be empty there.

    FROM node:20 AS build
    ARG NEXT_PUBLIC_API_URL
    ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
    RUN npm run build
  4. Keep secrets you only need at runtime (DB passwords, private API keys) with Build Variable OFF so they're not baked into the image layers. Only turn Build Variable ON for values the build genuinely inlines. For sensitive values you must use during build, enable Docker Build Secrets instead of a plain build arg.

  5. Redeploy with a fresh build so the new build-args take effect. If values still look stale, trigger a redeploy with the build cache cleared (cached layers will reuse the old empty values).

Verify it worked

After a fresh redeploy the real value appears in the built output instead of "undefined" — check the served HTML for SSR/inlined values, or the JS chunks / network requests for client-bundle values. The build log should show the variable passed as a build arg.

curl -s https://your-domain.com | grep -o 'api.your-domain.com' || echo 'not in root HTML — also check JS chunks / network tab'

Related Coolify errors

Have Emsden Studio fix it for you — from A$149

All Coolify deploy errors