Choose a deployment type
Vercel manages framework builds and server execution for you. A successful Vercel deployment does not mean the same app can be uploaded unchanged to a static host.
Static website: no Dockerfile
Use this path only if your app supports static export. Innext.config.mjs, merge this setting into your existing configuration:
out/index.html exists. The normal .next build directory is not a static publish directory. Neither dist nor public is the default Next.js export output.
App in a subfolder
For this example layout:
The build command starts at the repository root. The output directory also stays relative to the repository root, even after
cd in the build command. Replace frontend with your folder name. For example, surely-placed-fe uses cd surely-placed-fe && npm ci && npm run build and surely-placed-fe/out.
If the app is at the repository root, use npm ci && npm run build and out. These examples assume the default export output and an npm lockfile in the app folder. Workspaces may need installation from the workspace root instead.
A successful export does not prove nested routes work
Next.js can export a route such as/about to out/about.html, or to out/about/index.html with trailingSlash enabled. Spring Winter’s current Static website flow does not create Next.js-specific URL-to-file routing rules. CloudFront’s root index.html setting does not automatically resolve every nested directory.
Check direct visits and refreshes on nested routes after deployment. Do not turn on SPA rewrite as a general fix: it returns the root index.html for missing paths, rather than selecting each exported Next.js page. If your app needs clean Next.js routes and has no suitable routing configuration, use a Web server.
Static websites have no application process
Do not configurenpm start, a container port, a health path, or PORT for a Static website. There is no Next.js server running after the build. Keep your separate backend deployed separately and configure the frontend to call its public HTTPS URL.
Web server: preserve server features
Use Web servers when the app needs Next.js at request time. Spring Winter currently builds a container from your committed Dockerfile or pulls an existing public image. It does not generate the Dockerfile automatically. For an app and Dockerfile insidefrontend/, use:
The root directory selects the Docker build context. The Dockerfile path stays relative to the repository root. Inside this Dockerfile,
COPY . . copies from frontend/.
Build the application during image creation. For a standard next start deployment, bind to all interfaces:
start script runs next start. A standalone-output image instead runs its generated server.js; follow the Next.js self-hosting guidance for the packaging mode you choose. Keep the process port and Spring Winter container port consistent. If / redirects or requires login, add a dedicated endpoint that returns HTTP 200 without authentication and set that as the health path.
Environment variable gotchas
- Variables starting with
NEXT_PUBLIC_are embedded in browser JavaScript during the Next.js build. They are public. Never put private credentials in them. - On a Static website, add required values in Environment before the build, then redeploy after changes.
- On a Web server, Environment configures the running container. The current Docker build does not automatically receive these customer variables as build arguments. Changing a runtime value cannot replace a value already embedded in browser JavaScript.
- For a Web server that needs public build-time values, build a public image through your own build pipeline with those values supplied, or explicitly configure non-secret public values in your Docker build. Do not commit secret
.envfiles or copy them into an image. - Runtime secrets belong in the running service environment. Static exports have no private server runtime. Data included in exported pages is public.