Node API
Deploy a REST API or any Node server (Express, Fastify, Koa, NestJS, Hono): installed, built and run as a service on port 3000.
A REST API on Express, Fastify, Koa, NestJS or Hono (with @hono/node-server) is detected from package.json. Anything else runs with --template node.
cd my-api
kvbox deploy
# ✓ my-api is live at https://my-api.kvbox.appThe one rule
Listen on process.env.PORT, which is 3000:
import express from "express";
const app = express();
app.get("/health", (req, res) => res.json({ ok: true }));
app.listen(process.env.PORT ?? 3000);The first kvbox deploy asks for the port (default 3000); a server on another port answers it, or says so with kvbox deploy --port 8080. It is saved to kvbox.json.
What happens
- The source is shipped, without
node_modulesand.git. - The box installs it with your package manager (npm, pnpm or yarn, from the lockfile). devDependencies are installed too.
- It runs your
buildscript if you have one (NestJS, TypeScript), thenstart. Yourdevscript is never used.
start is required. A TypeScript server can start with tsx, since devDependencies are installed:
{
"scripts": {
"build": "tsc",
"start": "node dist/server.js"
}
}The app runs as the systemd service kvbox-app: restarted if it dies, back after a reboot. The deploy waits up to 30 seconds for it to answer on its port; if it never does (it crashed, or listens on another port), the deploy fails and prints the last lines of its log.
A redeploy installs and builds in a staging directory while the old version keeps serving, then swaps and restarts.
Environment variables
Database URLs, API keys: set them with kvbox env (--secret for the ones nobody should read back) and the server gets them. A database of its own is a Postgres box linked to this one.
In the box
kvbox exec my-api -- journalctl -u kvbox-app -n 100 # the server's log
curl https://my-api.kvbox.app/healthBigger boxes
The box is xs (1 vCPU, 2 GB of RAM) by default. Node uses one CPU, so on a bigger box add pm2 to your dependencies and make it your start script, to use every CPU and reload without a gap: "start": "pm2-runtime start ecosystem.config.js".