Deploy Node.js on Temps
Select the Autopack (Node.js) preset (nixpacks-node) and run up: Temps installs dependencies, runs your build script, starts your start script and routes HTTPS traffic to the port in PORT, with zero-downtime deploys. Express, Fastify, Hono and NestJS all deploy this way.
This guide describes how the nightly release channel builds your app, using the Autopack builder. Beta (v0.1.0-beta.56) also builds with Autopack, but some details below may differ. Earlier releases and the stable channel build with Nixpacks and behave differently. To run nightly, see Release channels.
For an overview of self-hosting Node.js, including costs, see Deploy Node.js to your own server. Every framework and the preset it needs is listed under Supported platforms.
Quickstart
From your project root, deploy with your preferred package manager:
npx @temps-sdk/cli up --preset nixpacks-node
Temps doesn't detect a plain Node.js service from its package.json, so choose the Autopack (Node.js) preset (nixpacks-node), as above or under Project → Settings → Build & deploy → Build → Framework.
With that preset, Temps installs dependencies with the package manager your lockfile or packageManager field points to, runs your build script if there is one, and starts the app. Your app is live with HTTPS in a few minutes.
The start command is the first of these that exists:
- The
web:line in aProcfile - Your
startscript - The
mainfile inpackage.json, run withnode - A common entry file, run with
node:server.js,server.mjs,index.js,index.mjs,app.js,src/index.js,dist/index.jsorbuild/index.js
If none of them exists, the build stops and asks for a start command. The Node.js version comes from .nvmrc, .node-version or engines.node in package.json, and defaults to 24. Temps sets NODE_ENV=production for you.
Express, Fastify, Hono and NestJS
Each framework only needs to listen on PORT and bind to 0.0.0.0:
import express from 'express'
const app = express()
app.get('/', (req, res) => res.send('ok'))
app.listen(Number(process.env.PORT) || 3000, '0.0.0.0')
Fastify listens on localhost unless you pass host, so don't skip it. For NestJS, make sure your start script runs the compiled output ("start": "node dist/main.js") rather than nest start, which compiles again on every boot; the build script (nest build) runs during the build. The Temps repository has a working NestJS example.
What Temps handles automatically
| Feature | How Temps handles it |
|---|---|
| Build | Installs dependencies, then runs your build script if there is one |
| Start | Procfile web: line, start script, main or a common entry file |
| HTTPS | Let's Encrypt certificate, auto-renewed |
| Port | Your app reads PORT, which Temps sets (3000 unless you change the project's port) |
| WebSockets | Fully supported via reverse proxy |
| Health checks | HTTP check on / at deploy time, or the path set in .temps.yaml |
| Preview deployments | Opt-in; once enabled, each branch gets its own preview environment |
Managed services
Create PostgreSQL or Redis under Databases → Create database, then link it from your project's Databases page. Temps injects the connection details into your app, such as POSTGRES_URL for PostgreSQL and REDIS_URL for Redis. It doesn't inject DATABASE_URL, so read POSTGRES_URL in your code or set DATABASE_URL yourself.
See Deploy with a Database for the full guide.
Environment variables
Set your own variables per environment:
npx @temps-sdk/cli environments vars set API_KEY "your-api-key" -e production
Changing a variable doesn't redeploy the app; deploy again for the new value to take effect.
Platform behavior
These rules apply to every app deployed on Temps, regardless of framework.
The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.
Health checks
After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.
- Path:
/(the root of your application) by default - Success: 2 consecutive responses with a 2xx, 3xx, 404 or 405 status code
- Timeout: 300 seconds (5 minutes) for the app to become healthy, fixed in v0.1.0-beta.56. If the app answers with error responses (other 4xx, or 5xx) for 60 seconds in a row, the deployment fails sooner. From the next release the timeout is configurable from 30 to 3600 seconds under Project → Settings → Build & deploy
- Retry interval: 2 seconds between successful checks, 5 seconds after an error response or a failed connection
Connection errors and other 4xx or 5xx responses are retried until the timeout; if the app hasn't passed by then, the deployment fails. The check runs once, at deploy time. To check a different path, add a .temps.yaml to your repository root:
health:
path: /healthOnly path is used. Other health fields (status, interval, timeout, retries) are accepted but currently have no effect.
/health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.Auto-injected environment variables
Temps injects these variables into every deployment automatically:
| Variable | Value | Description |
|---|---|---|
PORT | Resolved port | The port your app must listen on |
HOST | 0.0.0.0 | Bind address |
SENTRY_DSN | Auto-generated | Error tracking endpoint |
TEMPS_API_URL | Your Temps URL | Platform API endpoint |
TEMPS_API_TOKEN | Deployment token | Authentication for Temps SDKs |
OTEL_EXPORTER_OTLP_ENDPOINT | Your Temps OTLP URL | OpenTelemetry trace collection |
OTEL_SERVICE_NAME | Project name | Service identifier for traces |
You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.
Using a framework with server rendering? See the Next.js, Remix and SvelteKit guides. To control the image yourself, deploy with a Dockerfile.