Deploy Nuxt on Lizard
Run Nuxt on Lizard with Nitro’s node-server preset. The build produces .output/server/index.mjs, and a Node.js process serves pages and server routes on port 3000. For a generated site on port 80, use the static recipe below.
Configure the production build
Use the current Lizard CLI from Prepare the project. Version 0.3.95 excludes macOS archive metadata during uploads. If an older CLI reports a ._*.ts route error, update the CLI and upload again.
Set the preset in nuxt.config.ts:
export default defineNuxtConfig({
nitro: { preset: 'node-server' },
});Merge these scripts into package.json, keeping any other scripts your app needs:
{
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"start": "HOST=0.0.0.0 PORT=3000 node .output/server/index.mjs"
}
}The start script uses the Linux shell in the deployment container. lizardpack detects the nuxt dependency and runs the build and start scripts. A fresh Nuxt project may not include start; add it rather than assuming nuxt dev will serve the production build.
| Setting | Value |
|---|---|
| Build | npm run build |
| Server entry | .output/server/index.mjs |
| Start | npm run start |
| Service port | 3000 |
Test the built app
npm ci
npm run build
npm run startOpen http://localhost:3000, request an inner page directly, and call one of your server/api routes if present. Check that the build reports the Node server preset. A provider-specific Nitro preset can produce a different entry point.
Deploy
After CLI setup, run from the Nuxt app directory:
lizard init --name nuxt-app
lizard add --service web
lizard up --service web --port 3000
lizard logs --build --service web --json
lizard logs --service web --json
lizard ps --jsonKeep .nuxt/, .output/, node_modules/, and .env files out of the upload. Include source, config, and the lockfile. Existing service build/start overrides bypass the detection used here; see build decision order.
Runtime configuration
Declare runtime settings in runtimeConfig and configure their matching NUXT_* values for the service. Keep secrets outside runtimeConfig.public; the public part reaches the browser. Values used to prerender pages still affect the generated build, so check both request-time and prerendered routes after a change.
Use variables and secrets to configure the service and storage and recovery for durable data. Do not treat a local cache or session file as shared storage across replicas.
Troubleshooting
If the process reports a missing .output/server/index.mjs, inspect the preset and the build output. If it reports a missing start script, add the one above. If the site never becomes healthy, check the host and port.
For a purely generated Nuxt site, serve .output/public/ with a static Dockerfile and correct route handling. Do not start that output with the Node command above. The Nuxt deployment guide explains the Node and generated outputs; static routes and 404s covers the Lizard static server setup.
Generate a static site
For generated HTML, replace the Node preset with explicit prerender settings and change the build script to nuxt generate:
export default defineNuxtConfig({
nitro: {
prerender: { crawlLinks: true, routes: ['/'] },
},
});Add unlinked or dynamic routes to routes when the crawler cannot discover them. Run npm run build and check that .output/public/index.html and your inner route files exist. In the test with Nuxt 4.5.2, keeping preset: 'node-server' while switching only to nuxt generate produced the fallback pages without the site’s routes. A successful build alone did not establish that the export contained the site.
Use the Dockerfile and nginx configuration in static routes and 404s, with build script build, output directory .output/public, and service port 80. The static container does not run Nuxt server routes or read runtime config for already generated pages.
See tested versions and cloud results for the September 9, 2026 deployment checks and their limits.
Updated