# Deploy Node.js

A plain Node server - `http.createServer`, a WebSocket service, a worker with an HTTP health endpoint - deploys without any framework. Detection reads `package.json`, the [generated image](/platform/deployments/builds#dockerfiles-generated-or-your-own) runs on Node 22, and the default port is `8080`.

## Serve it

Listen on the routed [port](/create/build-settings#port) - `PORT` is set to it:

```js
const http = require('http');

http
  .createServer((req, res) => res.end('up'))
  .listen(process.env.PORT || 8080);
```

`server.listen(port)` binds all interfaces by default. Write logs to stdout/stderr for [runtime logs](/platform/observability#runtime-logs).

## Build and start

- **Install** follows your lockfile (`pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`) - exact installs with a lockfile present.
- A `build` script (TypeScript compile, bundling) runs during the image build via the [build command](/create/build-settings#build-command).
- The container starts your `start` script.

## Configuration and database

Read [environment variables](/platform/environment-variables#build-time-and-runtime) from `process.env` at startup - never bake them into the build. `DATABASE_URL` comes from the [Credentials tab](/platform/databases/connect).

## Related

- [Builds](/platform/deployments/builds): The generated Node image, step by step.
- [Dockerfile](/platform/frameworks/docker): Take over the image entirely.
- [Scaling](/create/scaling): Instances, concurrency, CPU target.
