From cd7850a6a7db921ab390079e1827ee38d4499784 Mon Sep 17 00:00:00 2001 From: wadefletch Date: Mon, 9 Feb 2026 16:48:11 -0600 Subject: [PATCH 1/3] feat: implement NITRO_UNIX_SOCKET and graceful shutdown env vars Wire NITRO_UNIX_SOCKET, NITRO_SHUTDOWN_DISABLED, and NITRO_SHUTDOWN_TIMEOUT through to srvx serve options in the Node, Bun, and Deno server presets. Co-authored-by: Cursor --- docs/2.deploy/10.runtimes/1.node.md | 8 +++----- src/presets/bun/runtime/bun.ts | 12 +++++++++++- src/presets/deno/runtime/deno-server.ts | 10 +++++++++- src/presets/node/runtime/node-server.ts | 12 +++++++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/docs/2.deploy/10.runtimes/1.node.md b/docs/2.deploy/10.runtimes/1.node.md index 475b4a0eae..4b18658b4e 100644 --- a/docs/2.deploy/10.runtimes/1.node.md +++ b/docs/2.deploy/10.runtimes/1.node.md @@ -31,12 +31,10 @@ You can customize server behavior using following environment variables: - `NITRO_PORT` or `PORT` (defaults to `3000`) - `NITRO_HOST` or `HOST` -- `NITRO_UNIX_SOCKET` - if provided (a path to the desired socket file) the service will be served over the provided UNIX socket. +- `NITRO_UNIX_SOCKET` - if provided (a path to the desired socket file) the service will be served over the provided UNIX socket (Node.js and Bun only). - `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL. -- `NITRO_SHUTDOWN_DISABLED` - Disables the graceful shutdown feature when set to `'true'`. If it's set to `'true'`, the graceful shutdown is bypassed to speed up the development process. Defaults to `'false'`. -- `NITRO_SHUTDOWN_SIGNALS` - Allows you to specify which signals should be handled. Each signal should be separated with a space. Defaults to `'SIGINT SIGTERM'`. -- `NITRO_SHUTDOWN_TIMEOUT` - Sets the amount of time (in milliseconds) before a forced shutdown occurs. Defaults to `'30000'` milliseconds. -- `NITRO_SHUTDOWN_FORCE` - When set to true, it triggers `process.exit()` at the end of the shutdown process. If it's set to `'false'`, the process will simply let the event loop clear. Defaults to `'true'`. +- `NITRO_SHUTDOWN_DISABLED` - Disables the graceful shutdown feature when set to `'true'`. Defaults to `'false'`. +- `NITRO_SHUTDOWN_TIMEOUT` - Sets the amount of time (in milliseconds) before a forced shutdown occurs. Defaults to `5000` milliseconds. ## Cluster mode diff --git a/src/presets/bun/runtime/bun.ts b/src/presets/bun/runtime/bun.ts index 7407e9e625..d01c9d3a35 100644 --- a/src/presets/bun/runtime/bun.ts +++ b/src/presets/bun/runtime/bun.ts @@ -13,7 +13,15 @@ const port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort; const host = process.env.NITRO_HOST || process.env.HOST; const cert = process.env.NITRO_SSL_CERT; const key = process.env.NITRO_SSL_KEY; -// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO +const socketPath = process.env.NITRO_UNIX_SOCKET; + +const _shutdownTimeout = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10); +const gracefulShutdown = + process.env.NITRO_SHUTDOWN_DISABLED === "true" + ? false + : _shutdownTimeout > 0 + ? { gracefulTimeout: _shutdownTimeout / 1000 } + : undefined; const nitroApp = useNitroApp(); @@ -35,7 +43,9 @@ serve({ hostname: host, tls: cert && key ? { cert, key } : undefined, fetch: _fetch, + gracefulShutdown, bun: { + unix: socketPath, websocket: import.meta._websocket ? ws?.websocket : undefined, }, }); diff --git a/src/presets/deno/runtime/deno-server.ts b/src/presets/deno/runtime/deno-server.ts index 005af67e43..75c9899263 100644 --- a/src/presets/deno/runtime/deno-server.ts +++ b/src/presets/deno/runtime/deno-server.ts @@ -14,7 +14,14 @@ const port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort; const host = process.env.NITRO_HOST || process.env.HOST; const cert = process.env.NITRO_SSL_CERT; const key = process.env.NITRO_SSL_KEY; -// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO + +const _shutdownTimeout = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10); +const gracefulShutdown = + process.env.NITRO_SHUTDOWN_DISABLED === "true" + ? false + : _shutdownTimeout > 0 + ? { gracefulTimeout: _shutdownTimeout / 1000 } + : undefined; const nitroApp = useNitroApp(); @@ -35,6 +42,7 @@ serve({ hostname: host, tls: cert && key ? { cert, key } : undefined, fetch: _fetch, + gracefulShutdown, }); trapUnhandledErrors(); diff --git a/src/presets/node/runtime/node-server.ts b/src/presets/node/runtime/node-server.ts index 6356f4dc42..6d34676222 100644 --- a/src/presets/node/runtime/node-server.ts +++ b/src/presets/node/runtime/node-server.ts @@ -13,7 +13,15 @@ const port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort; const host = process.env.NITRO_HOST || process.env.HOST; const cert = process.env.NITRO_SSL_CERT; const key = process.env.NITRO_SSL_KEY; -// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO +const socketPath = process.env.NITRO_UNIX_SOCKET; + +const _shutdownTimeout = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10); +const gracefulShutdown = + process.env.NITRO_SHUTDOWN_DISABLED === "true" + ? false + : _shutdownTimeout > 0 + ? { gracefulTimeout: _shutdownTimeout / 1000 } + : undefined; const nitroApp = useNitroApp(); @@ -22,6 +30,8 @@ const server = serve({ hostname: host, tls: cert && key ? { cert, key } : undefined, fetch: nitroApp.fetch, + gracefulShutdown, + node: socketPath ? { path: socketPath } : undefined, }); if (import.meta._websocket) { From 4218d87820db380f410e64786a70626dccb3a708 Mon Sep 17 00:00:00 2001 From: wadefletch Date: Mon, 9 Feb 2026 16:48:39 -0600 Subject: [PATCH 2/3] docs: add env var documentation to bun and deno runtime pages Co-authored-by: Cursor --- docs/2.deploy/10.runtimes/bun.md | 11 +++++++++++ docs/2.deploy/10.runtimes/deno.md | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/2.deploy/10.runtimes/bun.md b/docs/2.deploy/10.runtimes/bun.md index e619cdadeb..140d64b5b4 100644 --- a/docs/2.deploy/10.runtimes/bun.md +++ b/docs/2.deploy/10.runtimes/bun.md @@ -17,3 +17,14 @@ bun run ./.output/server/index.mjs ``` :read-more{to="https://bun.sh"} + +### Environment Variables + +You can customize server behavior using following environment variables: + +- `NITRO_PORT` or `PORT` (defaults to `3000`) +- `NITRO_HOST` or `HOST` +- `NITRO_UNIX_SOCKET` - if provided (a path to the desired socket file) the service will be served over the provided UNIX socket. +- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL. +- `NITRO_SHUTDOWN_DISABLED` - Disables the graceful shutdown feature when set to `'true'`. Defaults to `'false'`. +- `NITRO_SHUTDOWN_TIMEOUT` - Sets the amount of time (in milliseconds) before a forced shutdown occurs. Defaults to `3000` milliseconds. diff --git a/docs/2.deploy/10.runtimes/deno.md b/docs/2.deploy/10.runtimes/deno.md index cc8a0cfdf5..9613ac4ab4 100644 --- a/docs/2.deploy/10.runtimes/deno.md +++ b/docs/2.deploy/10.runtimes/deno.md @@ -18,6 +18,16 @@ NITRO_PRESET=deno_server npm run build deno run --unstable --allow-net --allow-read --allow-env .output/server/index.ts ``` +### Environment Variables + +You can customize server behavior using following environment variables: + +- `NITRO_PORT` or `PORT` (defaults to `3000`) +- `NITRO_HOST` or `HOST` +- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL. +- `NITRO_SHUTDOWN_DISABLED` - Disables the graceful shutdown feature when set to `'true'`. Defaults to `'false'`. +- `NITRO_SHUTDOWN_TIMEOUT` - Sets the amount of time (in milliseconds) before a forced shutdown occurs. Defaults to `3000` milliseconds. + ## Deno Deploy :read-more{to="/deploy/providers/deno-deploy"} From 34820648d5efe70e1bdcf8f6e7b118c03bd92172 Mon Sep 17 00:00:00 2001 From: wadefletch Date: Mon, 9 Feb 2026 18:39:45 -0600 Subject: [PATCH 3/3] docs(node): fix handler preset name and export The Handler (advanced) section referenced preset `node` and export `listener`, but `node` is an alias for `node-server` (not the middleware handler). The actual preset name is `node-middleware` and the export is `middleware`. Co-authored-by: Cursor --- docs/2.deploy/10.runtimes/1.node.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/2.deploy/10.runtimes/1.node.md b/docs/2.deploy/10.runtimes/1.node.md index 4b18658b4e..71b374770e 100644 --- a/docs/2.deploy/10.runtimes/1.node.md +++ b/docs/2.deploy/10.runtimes/1.node.md @@ -50,18 +50,18 @@ In addition to environment variables from the `node_server` preset, you can cust ## Handler (advanced) -**Preset:** `node` +**Preset:** `node_middleware` -Nitro also has a more low-level preset that directly exports a function with `(req, res) => {}` signature usable for middleware and custom servers. +Nitro also has a more low-level preset that directly exports a Node.js compatible handler usable for middleware and custom servers. -When running `nitro build` with the Node preset, the result will be an entry point exporting a function with the `(req, res) => {}` signature. +When running `nitro build` with the Node middleware preset, the result will be an entry point exporting a `middleware` handler. **Example:** ```js import { createServer } from 'node:http' -import { listener } from './.output/server' +import { middleware } from './.output/server' -const server = createServer(listener) +const server = createServer(middleware) server.listen(8080) ```