Node.js hosting for Express, NestJS and Fastify on servers you own
Deployment runs Node.js apps on your own Ubuntu or Debian servers the way a careful operator would: the right Node LTS per app, a process manager that restarts crashed workers, nginx or Caddy in front with TLS, and releases that switch only after the new build answers its health check. Push to your branch and the new version goes live without dropping a request.
What Deployment reads from your package.json
Deployment opens the repository and looks at the files that describe a Node app. The engines.node field (or .nvmrc and .node-version) picks the Node version. The lockfile picks the package manager: package-lock.json for npm, pnpm-lock.yaml for pnpm, yarn.lock for Yarn. Dependencies tell it the framework: express, @nestjs/core or fastify. The build and start scripts become the build step and the process command, and bullmq or a worker script adds a background worker next to the web process.
- Node LTS version from engines,
.nvmrcor.node-version - npm, pnpm or Yarn from the lockfile, with a clean install on every release
- TypeScript builds through your own
buildscript (tsc, nest build, tsup or esbuild) - A worker process when BullMQ or a separate worker entry point is present
What Deployment installs for Node.js hosting
Each server is provisioned with a firewall, key-only SSH, unattended security updates and swap. On top of that Deployment installs Node LTS through a version manager so different sites can run different versions, the package manager your lockfile asks for, nginx or Caddy as the reverse proxy with WebSocket upgrade headers already set, and Redis when your app uses BullMQ or sessions. Every app runs as its own system user and listens on a private port that only the proxy can reach.
A Node deploy script for Express and NestJS
The script below is what Deployment writes for a NestJS API with pnpm. It runs in the new release folder while the old process keeps serving traffic, and you edit it in the panel whenever your build changes.
After the script, Deployment starts the new process on a fresh port, calls your health route, and only then points the proxy at it.
cd "$RELEASE_PATH" corepack enable pnpm install --frozen-lockfile pnpm run build pnpm prune --prod npx prisma migrate deploy
PM2 or systemd, your choice of process manager
Some teams already know PM2 and want its cluster mode and log commands; others want plain systemd units with restart rules and journald logs. Deployment supports both per site. With PM2 it generates an ecosystem file and uses pm2 reload for graceful restarts across cluster workers. With systemd it writes a unit with Restart=on-failure, memory limits and an environment file. Either way, crashed processes come back automatically, and stdout and stderr stream into the app log view in the panel.
Background jobs with BullMQ and cron
BullMQ workers run as separate daemons, so a heavy job never blocks your HTTP process. On deploy Deployment sends SIGTERM and waits for worker.close() to finish active jobs before the worker starts again on the new code. Scheduled tasks can run as cron jobs (node dist/cli.js cleanup) with each run's output stored in the cron log, or as BullMQ repeatable jobs if you prefer to keep scheduling inside the app.
Zero downtime Node.js deploys and rollback
Node apps keep state in memory, so a naive restart drops in-flight requests. Deployment builds each release in its own folder, starts the new process next to the old one, and checks the health route (for example /health returning 200) before the switch. Then the proxy moves to the new process and the old one receives SIGTERM, finishes open requests and exits. If the health check fails, nothing changes for your users. Previous releases stay on disk, so rollback is one click and does not need a rebuild. The full mechanics are on zero downtime deployment, and branch and webhook setup is on deploy from git.
- Listen for SIGTERM and close the HTTP server so Deployment can drain connections
- Keep migrations backward compatible so a rollback does not meet an unknown column
PostgreSQL, MySQL and Redis for Node apps
Create PostgreSQL, MySQL or MariaDB databases with their own users and grants, on the app server or on a dedicated database server, and add Redis for queues, caching and sessions. Connection strings land in encrypted environment variables per environment, and the panel shows a diff of every change before the next deploy. Nightly or hourly backups go to your own S3-compatible bucket. Frontend apps built with Next.js have their own guide on nextjs hosting.
Which plan fits your Node.js hosting
| Plan | Monthly | Yearly, per month | Servers | Team members |
|---|---|---|---|---|
| Starter | 49 USD | 24 USD | 3 | 1 |
| Team | 199 USD | 99 USD | 15 | 10 |
| Agency | 499 USD | 249 USD | 60 | 30 |
| Enterprise | 1 499 USD | 749 USD | 250 | unlimited |
One developer with an API, a worker and a staging copy fits Starter. A team with several services, separate environments and people who should only deploy (not delete servers) fits Team, with roles and the audit log. Yearly billing saves 50 percent on every plan.
Node.js hosting questions
Which Node versions can I run?
Any active or maintenance LTS release. Each site picks its own version from engines, .nvmrc or the panel, so one server can host apps on different Node versions.
Do WebSockets and Server-Sent Events work?
Yes. The reverse proxy is set up with the upgrade headers and long timeouts that WebSockets and SSE need, and you can tune timeouts per site.
Can I run several instances of one app?
Yes. Use PM2 cluster mode or several systemd instances behind the same proxy upstream. For more capacity, add servers and a load balancer from your cloud.
Can I try Deployment before I pay?
Yes. The home page has a free one-time demo: paste a public repository URL and see the detected stack, the server plan and the first lines of the deploy script. Plans start at 49 USD a month, or 24 USD a month billed yearly.
Put your Node app on a server you control
Connect a VPS or a cloud account and push your next release.
$ git push origin main
✓ build release 20261019-142210
✓ health check 200
✓ switch current 0.4 s
$