Your website opens in the editor, then disappears when you close the terminal. If a Node process handles requests, check that process before choosing hosting. This guide gives you observable signals: the right port, routes, health, shutdown and state after a restart.
We use Señal, an original MIT example, without external dependencies, accounts, payments or a database. Its page reads the server’s version and uptime. Copying its files to static hosting cannot keep that process running.
Pin the version and start the process
Install Node 22.23.3, published by Node.js, and check that node --version returns v22.23.3. Retain the MIT licence and lockfile when copying the example.
git clone https://github.com/ocentelles/hostbrid-example-service.git
cd hostbrid-example-service
git checkout dffe40abc37323cb9a84f172f804ed91670e465e
node --version
npm ci
npm run check
npm test
PORT=8080 npm start
npm ci uses the lockfile and fails when it disagrees with package.json. This example has no external packages. npm start keeps a server running; it does not generate dist. Open http://localhost:8080/ and keep that terminal open while checking from another.
The code listens on 0.0.0.0:8080. PORT can change the port; its value must match the service’s configured port. 0.0.0.0 accepts connections from outside the process: it is not a URL to visit, and native execution may allow access from your local network.
Reproduce the image without publishing it publicly
With a Docker engine already available, first stop the native process to release 8080:
docker build -t hostbrid-service-check:dffe40a .
docker run --rm --name hostbrid-service-check -e PORT=8080 \
-p 127.0.0.1:8080:8080 hostbrid-service-check:dffe40a
The Dockerfile pins Node 22.23.3 Alpine by digest. It runs Node directly as a non-root user. This port mapping publishes 8080 only on your computer’s loopback interface. EXPOSE documents a port; it does not publish one itself. These local commands do not configure a domain or HTTPS.
For this localhost restriction, use Docker Engine 28.0.0 or later with the default bridge network. Docker warns that on older versions other hosts on the same L2 segment can reach ports published to localhost. Check the server version with docker version; we did not test a local Docker daemon. Official port-publishing warning.
Check behaviour that can fail
From another terminal:
curl -fsS http://127.0.0.1:8080/healthz
curl -fsS http://127.0.0.1:8080/status.json
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/missing
curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:8080/healthz?check=1'
/healthz should return JSON with status: ok; /status.json includes version, bootId, uptimeSeconds and requests. The missing route and undeclared query must return 404, without substituting the home page. Also open /service.css and /signal.svg: a working home page does not prove its assets are available.
| Signal | What to check |
|---|---|
| Connection refused | Stopped process, different port or missing mapping. |
| Home 200, CSS 404 | Asset routes or image context. |
| Health 200, real feature fails | This endpoint checks this demo, not your application’s dependencies. |
| Uptime resets to zero | The process restarted; check bootId too. |
Three different health controls
/healthz is an application route. The Dockerfile’s HEALTHCHECK runs a helper inside the container. Kubernetes probes are configured separately: readiness controls traffic, liveness restarts and startup the initial launch. A Dockerfile does not configure those probes automatically.
Our test successfully ran the helper. That is not evidence of a Docker daemon’s health status or Kubernetes probes on a published service.
Shutdown and memory: check the boundary
docker stop --timeout 10 hostbrid-service-check
The example handles SIGTERM by stopping new connections and waiting for active requests, with an internal five-second deadline. The container test verified exit 0 and a closed port by signalling the verifier’s child server. It did not verify a rollout or Kubernetes delivering SIGTERM to Node as PID1.
After starting again, bootId changes and the counter resets. Uptime and requests live in ephemeral memory, not persistent storage. Probes count as requests too: this is not a visitor counter. Durable data needs separately designed and tested storage, backups and recovery.
What we tested, and what publication still needs
On 8 October 2026 we built an OCI image and ran 11 checks in a temporary Job: version, health, state, uptime, assets, 404s, shutdown and memory reset. The Job and its own image references were cleaned up. This did not create a hosting service or demonstrate public HTTPS, customer OAuth or automatic deployment after a push.
For an application with a running process on Hostbrid Projects, review a plan that includes services and has available quota, the root Dockerfile, service port and variables. Static-site quota does not authorise permanent processes. Check current pricing before creating resources; this example does not demonstrate free services. Domain, HTTPS, probes and persistence each need verification with your application.
If your application needs a website, API and database in separate containers, see the Docker Compose VPS deployment guide. It covers a multi-service stack; this page focuses on checking one Node process.
Once the process works, compare the actual deployment paths in the Node.js hosting guide: Sites, Git-based Projects and a VPS have different domain and operations requirements.