Deploy a Node.js app

Deploy a Node.js server on Hangar, such as Express, Fastify or NestJS, from a Git repository, with a database, WebSockets and HTTPS.

Updated

Any Node.js server deploys on Hangar from its repository: Express, Fastify, NestJS, Hono, Koa or plain http. The app runs as a long-lived process, so WebSockets, queues and in-memory state within a process work as they do locally.

Before you start

  • A Node.js app in a Git repository with a start script, and a build script if it needs compiling:
{
  "engines": { "node": "22.x" },
  "scripts": {
    "build": "tsc",
    "start": "node dist/server.js"
  }
}

1. Listen on the right address

The server must listen on 0.0.0.0 and on a port you know:

const port = Number(process.env.PORT) || 3000;
app.listen(port, "0.0.0.0");

2. Create the service

Create a project, add a service and pick your repository and branch. Leave the builder on Automatic. It installs dependencies with the package manager your lockfile belongs to (npm, pnpm, Yarn or Bun), runs build if it exists and starts the app with start.

3. Set the variables

Add your configuration in the Variables tab. Hangar sets PORT to the domain's container port, so you don't need to:

NODE_ENV=production

4. Deploy and add a domain

Deploy the service. In Settings → Networking, add a domain with container port 3000 and HTTPS on.

Behind the proxy

Hangar terminates TLS and forwards the request. For Express to report the right protocol and client address:

app.set("trust proxy", true);

Fastify takes trustProxy: true in its options.

Shut down cleanly

On every deploy the old container receives SIGTERM before it is stopped. Close the server on that signal so requests in flight finish:

process.on("SIGTERM", () => {
  server.close(() => process.exit(0));
});

Adding a database

Add PostgreSQL, MySQL, MongoDB or Redis to the project, in the same region, and set its internal connection URL on the app as DATABASE_URL or REDIS_URL. To run migrations on each release, chain them in the start script:

"start": "prisma migrate deploy && node dist/server.js"

Monorepos

For a workspace with several apps, set each service's root directory, or build with a Dockerfile to control exactly what is installed. See Builds.

Troubleshooting

  • 502 on the domain: the app listens on 127.0.0.1 or on a different port from the domain's container port.
  • The build passes but the app exits: start points at a file the build did not produce. Check the output directory.
  • Wrong Node.js version: add engines.node to package.json.

Frequently asked questions

Which Node.js version does Hangar use?
The automatic builder uses the version your repository asks for, from the engines field of package.json or a .nvmrc or .node-version file. Pin one so that builds do not change under you.
Do WebSockets work on Hangar?
Yes. A Node.js service is a long-lived server in a container, so WebSocket and Server-Sent Events connections stay open as they do on a server you run yourself.
Can I deploy a TypeScript Node.js app?
Yes. Add a build script that compiles the project and a start script that runs the compiled output. The automatic builder runs build during the build and start when the container starts.

Deploy your app on Hangar

Connect a repository and it is live in minutes.

Start deploying