What Lannzo expects
The build installs dependencies, runs your build script, and packages dist, package.json and the installed node_modules. The checks below run during the build, so a mismatch fails with a named error.
| In your project | What Lannzo expects |
|---|---|
package.json → scripts.build | A build script. NestJS projects must define one; the build fails with `NEST_BUILD_SCRIPT_MISSING` otherwise. |
dist/main.js | The compiled entrypoint. It must exist exactly at this path, which is the Nest CLI default. |
process.env.PORT | The runtime injects `PORT`. An application listening on a fixed port never receives traffic. |
0.0.0.0 | Listen on all interfaces. Binding to `localhost` makes the application unreachable from outside its own container. |
Prepare the project
Read the port from the environment and bind to every interface:
// src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000, "0.0.0.0");
}
void bootstrap();Keep the build script the Nest CLI generates. It compiles to dist, with dist/main.js as its entrypoint:
{
"scripts": {
"build": "nest build"
}
}Deploy it
Link the directory once, and deploy. Preview gets its own URL, so an API can be checked before it reaches production.
lannzo link --project my-api
lannzo deploy
lannzo deploy --prodTo deploy from GitHub instead of your machine, connect the repository once. With --auto-deploy, every push to the production branch deploys on its own; without it, lannzo deploy --git deploys the head commit when you decide to.
lannzo repo connect --repository acme/my-api --branch main --auto-deploy
lannzo deploy --gitEnvironment variables
Give an API its configuration as runtime variables, and mark anything sensitive as a secret: connection strings, tokens, signing keys. Secrets are written but never read back, and never appear in a listing or a log.
lannzo env set DATABASE_URL --environment production --secret --target runtime
lannzo env list --environment productionOperate the runtime
A release keeps serving until you replace it. Restarting creates a new revision from the same artifact, picking up the current variables without redeploying; stopping withdraws traffic until you start it again.
lannzo runtime restart --environment production
lannzo logs --follow --source runtimeMonorepos
In a monorepo, point Lannzo at the API's directory. Its dist/main.js is resolved inside that directory, not at the repository root.
lannzo project set-root-directory apps/apiOverride the configuration
Lannzo detects the framework on every deployment. Setting it explicitly marks the selection as manual, so detection stops overriding it, and it is what makes a custom build or start command take effect — commands saved without a manual framework are ignored by the build.
Use --auto-framework, --auto-build-command and --auto-start-command to clear a manual value and go back to detection and the framework defaults.
lannzo project config --framework nestjs
lannzo project config --framework nestjs --build-command "pnpm build"When a build fails
`NEST_ENTRYPOINT_MISSING`
The build succeeded but produced no dist/main.js. A changed outDir in tsconfig.json, or a build that emits somewhere else, are the usual causes.
The deployment never becomes healthy
The process starts but nothing answers on the injected port. Check that main.ts listens on process.env.PORT and on 0.0.0.0, then read lannzo logs --source runtime for what the process printed before it went quiet.
Several frameworks detected
If the same package.json declares more than one supported framework, the build stops with FRAMEWORK_DETECTION_AMBIGUOUS instead of guessing. Pick one with lannzo project config --framework <framework>.