Deploy Next.js on Lizard
Run Next.js on Lizard as a Node.js server with next build and next start. The server handles request-time rendering, Route Handlers, and Server Actions. If every route can be built ahead of time, follow Next.js static export instead.
Build settings
| Setting | Value |
|---|---|
| Project root | Directory containing package.json and the Next.js configuration |
| Build script | next build |
| Start script | next start --hostname 0.0.0.0 --port 3000 |
| Build output | .next/ |
| Service port | 3000 |
| Runtime | Node.js |
Prepare the app
Keep next, react, and react-dom in your dependencies and commit your lockfile. Merge these scripts into package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start --hostname 0.0.0.0 --port 3000"
}
}Use the standard Next.js output for this guide. output: 'export' needs a static server, and output: 'standalone' needs its own server.js launch and asset layout. Neither uses this next start recipe unchanged.
Select a supported Node major version in .nvmrc, such as 22. Exclude .next/, node_modules/, and .env* from the uploaded source; keep a sample environment file free of secrets if needed.
Test the production build locally
npm ci
npm run build
npm run startIn another terminal, open http://localhost:3000 and test an inner route. If the app has an API or Server Action, test it too. Passing the development server check alone does not prove that the production build works.
Deploy
After installing Lizard CLI and signing in, run from the app directory:
lizard init --name nextjs-app
lizard add --service web
lizard up --service web --port 3000
lizard logs --build --service web --json
lizard logs --service web --json
lizard ps --jsonLizard detects the next dependency and runs the build and start scripts. These commands assume the service has no existing build or start overrides. Use the URL in the deploy output to repeat the local checks.
Environment variables and data
NEXT_PUBLIC_* values become part of the browser bundle during the build. With lizard up, Lizard passes no variables to the build: commit public values in .env.production (the .gitignore from create-next-app can exclude .env*; allow that file). On a GitHub service, Lizard writes the service’s NEXT_PUBLIC_* variables into the build; see build-time variables. Keep credentials in server-only variables and configure them for the service through variables and secrets. No other service variables reach the build, so code that fetches data while building cannot read them. A runtime restart does not change already generated HTML or JavaScript.
Local cache files and uploaded files do not form a shared store across replicas. Review Next.js cache and Server Action requirements before scaling beyond one replica. Put durable app data in a database or object storage, and read storage and recovery.
Troubleshooting
| Symptom | Check |
|---|---|
Missing script: start | Add the production start script above; next dev is for local development. |
| App never becomes healthy | Match --port 3000 to the start command and bind to 0.0.0.0. |
| Public API URL still has its old value | Change it in .env.production and upload again, or change the variable on a GitHub service so it rebuilds. |
| Build cannot reach a database | Check whether a route fetches data at build time and whether that dependency is reachable then. |
Static export fails under next start | Follow the separate static export guide. |
The Next.js self-hosting guide covers framework-level cache, image, and multi-instance behavior. For deployment errors, see service never healthy.
See tested versions and cloud results for the September 9, 2026 deployment checks and their limits.
Updated