WEB HOSTING

How to Deploy a Node.js REST API with Environment Variables in 2026

Build and test a working Node.js REST API, protect routes with an environment-stored API key, then deploy it to a compatible cloud server or Volyx allocation with HTTPS and health checks.

A command-line bot can work without accepting visitors. A REST API is different: another application must be able to send it HTTP requests and receive predictable responses. That distinction matters when you move a Node.js project from your laptop to a hosted server. Starting a process successfully is not the same thing as publishing a secure, reachable API.

This guide builds a tiny but working Node.js REST API in 2026 using built-in Node modules, stores its configuration in environment variables, and shows you how to test, troubleshoot and deploy it. The same skills apply to a Discord bot dashboard, an integration service, a small game-server companion API or a personal developer project. We’ll use Volyx as an example of a hosting control-panel workflow without assuming that every hosting plan automatically provides a public HTTPS endpoint.

Quick answer: Create an HTTP server, give it routes, read its port and secrets from environment variables, run it on a host that supports your Node.js version, and publish it behind an HTTPS endpoint that can actually reach your service. Validate requests and protect non-public routes. You will learn each part, not just copy a command that prints “Server running.”

An original purple and navy Volyx illustration of a Node.js API, servers and protected configuration

Important Volyx distinction: Volyx provides managed hosting workflows for developers and bots, with resources tied to its Coins-based service. However, the ability to run a Node.js process does not automatically mean your allocation has a public HTTP ingress, reverse proxy, custom domain or TLS certificate. Check the controls available under your server’s Network and Startup settings. The application in this tutorial can run locally or within a compatible Node.js allocation; a public API needs an explicitly supported inbound route.

What will you build?

Instead of another “Hello World” server that is difficult to extend, we’ll build a minimal Notes API with four useful behaviors. You can copy the included example project from this article’s download package, or create the files yourself.

EndpointHTTP methodWhat it doesAPI key required?
/healthzGETConfirms the process is respondingNo
/api/notesGETLists notes created in this processYes
/api/notesPOSTAdds a note from a JSON bodyYes
/api/notes/:idDELETEDeletes a note by UUIDYes

Each response is JSON, and each route uses an appropriate HTTP status code. The example rejects oversized POST bodies, checks the content type, compares API keys safely, and never returns a secret in an error response. It uses the standard node:http and node:crypto packages, so you won’t need to download third-party runtime libraries.

One limitation matters: notes are held in memory. They disappear when the process restarts, scales to another instance or is redeployed. This design keeps the learning example simple; it is not a substitute for PostgreSQL, SQLite or another database when data must survive a restart.

Diagram of a request passing through HTTPS, the Node.js process and protected JSON API routes

Requirements before you deploy a Node.js REST API

Prepare these items before editing files:

  • Node.js 22 or newer for the example and scripts in this guide. Node.js 22 supports the built-in --env-file command-line option. Verify the exact version supplied by your host.
  • A project directory containing server.mjs and package.json.
  • A secure place for API_KEY and other configuration values, such as local .env for development or the provider’s environment-variable controls.
  • Access to a terminal or panel Console so you can read startup errors and logs.
  • For public access, a supported incoming TCP/HTTP route, DNS if using a domain, and HTTPS termination. These are separate hosting capabilities.
  • A few minutes to test status codes before connecting your real bot, website or database.

You can start entirely on your own computer. You do not need to buy a domain for local testing. Do not expose a demo server directly to the internet just to complete the exercises.

Understand the difference between a process, a port and a website

There are three connected but distinct parts to deploying an API:

  1. The Node.js process: your code starts and remains running. If it crashes or the host suspends the allocation, requests stop working.
  2. The listening address and port: Node listens on an interface such as 127.0.0.1 for local-only access or a container interface when a proxy must reach it. The correct choice depends on network isolation and provider instructions.
  3. The public HTTPS entry point: clients reach a domain or provider URL. A trusted proxy or supported ingress routes traffic to your application and handles TLS securely.

A Pterodactyl-style dashboard may let you create and start a process while still providing no automatic public URL for your API. Likewise, a panel showing an allocated game port does not prove that HTTP traffic is routed correctly or that HTTPS is configured. Test internal reachability first; ask the hosting provider which public ingress features are supported before advertising an API endpoint.

A typical deployment is: Client → HTTPS endpoint / trusted proxy → Node.js app → JSON response. If any link is missing, the app might show as “online” while its public URL returns 404, 502 or a timeout.

Step 1: Create the project structure

Create a directory named notes-api. You only need these files:

notes-api/
├── server.mjs
├── package.json
├── .env.example
└── .gitignore

The sample package file is deliberately small:

{
  "name": "volyx-notes-rest-api-example",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "node server.mjs",
    "start:local": "node --env-file=.env server.mjs",
    "check": "node --check server.mjs"
  },
  "engines": { "node": ">=22" }
}

The start command expects the environment to be supplied by your hosting platform. The start:local command reads a local .env file while developing. Using separate commands prevents you from accidentally requiring a .env file to exist on a production allocation that already injects environment variables securely.

No npm install is necessary for this specific example because it imports only built-in Node.js modules. In other projects, npm ci is typically preferable when you have a checked-in lockfile and reproducible dependencies. Don’t invent a node_modules directory or upload one built for a different operating system when the host can install its own packages.

Step 2: Use environment variables for configuration

Hardcoding your API key in server.mjs makes accidental disclosure much easier. Put private configuration in environment variables instead. Node.js exposes them through process.env; recent Node releases also support loading a development file with --env-file. Read the official Node.js environment-variable documentation.

Create .env.example to document what the project expects:

HOST=127.0.0.1
PORT=3000
API_KEY=replace-this-with-a-random-secret-of-at-least-32-chars

The placeholder above is not a secure key. Copy .env.example to .env for local testing and generate a fresh random value. For example:

node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"

Copy the output into your private local .env file. Never paste the real value into a screenshot, public repository, support ticket or article comment. In .gitignore, exclude .env but permit the harmless example file:

.env
.env.*
!.env.example
node_modules/

The actual runtime must see a valid API_KEY, HOST and PORT. On a managed panel, use its documented environment-variable or secret controls. If a field is called SERVER_PORT, MAIN_FILE or something else by the provider, don’t assume it maps automatically to the application’s PORT: verify the startup configuration or adapt the code deliberately.

Graphic showing the separation between example configuration, private production secrets and source code

Why use HOST=127.0.0.1 locally?

Loopback binding accepts requests from the same machine and is a safer starting point for development. In an isolated container, a host-managed reverse proxy might require the app to listen on 0.0.0.0 so the proxy can reach it. That setting alone does not protect or publish your API: access still depends on network rules and the proxy. Use the host’s documented interface and port; do not open firewall ports blindly on a shared server.

Step 3: Write the API server

Save this in server.mjs. It illustrates request routing, a simple authentication check and JSON responses. The complete tested version with all routes is included in this article’s downloadable project; the key implementation pieces are shown here so you can understand the behavior rather than paste a wall of code without explanation.

import { createServer } from 'node:http';
import { timingSafeEqual } from 'node:crypto';

const PORT = Number(process.env.PORT ?? 3000);
const HOST = process.env.HOST ?? '127.0.0.1';
const API_KEY = process.env.API_KEY ?? '';

if (!Number.isInteger(PORT) || PORT < 1 || PORT > 65535) {
  throw new Error('PORT must be a valid TCP port');
}
if (API_KEY.length < 32) {
  throw new Error('Set a random API_KEY of at least 32 characters');
}

function authenticated(req) {
  const supplied = req.headers['x-api-key'];
  if (typeof supplied !== 'string') return false;
  const left = Buffer.from(supplied);
  const right = Buffer.from(API_KEY);
  return left.length === right.length && timingSafeEqual(left, right);
}

function reply(res, status, data) {
  res.writeHead(status, {
    'Content-Type': 'application/json; charset=utf-8',
    'Cache-Control': 'no-store',
    'X-Content-Type-Options': 'nosniff'
  });
  res.end(JSON.stringify(data));
}

const server = createServer((req, res) => {
  if (req.url === '/healthz' && req.method === 'GET') {
    return reply(res, 200, { status: 'ok' });
  }
  if (!authenticated(req)) {
    return reply(res, 401, { error: 'API key required or invalid' });
  }
  return reply(res, 404, { error: 'Route not found' });
});

server.listen(PORT, HOST, () => {
  console.log(`API listening on ${HOST}:${PORT}`);
});

That short extract explains the moving parts; use the complete example-api/server.mjs from this package when you want the Notes endpoints. The complete version also validates incoming JSON, imposes a 16 KiB request-body cap, supports UUID-based deletion and adds graceful shutdown handlers.

The key check is intentionally minimal. An API key can be copied or leaked and does not replace a complete identity and authorization system for multi-user applications. Sensitive production APIs require stronger access rules, audit logging and controlled key rotation. See the OWASP REST Security Cheat Sheet.

Step 4: Start the API and test it locally

Open a terminal in the project folder, copy .env.example to .env, and replace the placeholder key. Start with:

node --env-file=.env server.mjs

Or use the npm script:

npm run start:local

You should see a startup message similar to:

API listening on 127.0.0.1:3000
Data is stored in memory and is erased on restart.

First test the public health-check route, which intentionally avoids reporting secrets, environment variables or database details:

curl -i http://127.0.0.1:3000/healthz

Expected result:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"status":"ok"}

Next, read the notes with your locally generated key. Replace YOUR_LOCAL_KEY with the value in your private .env file:

curl -i http://127.0.0.1:3000/api/notes \
  -H 'x-api-key: YOUR_LOCAL_KEY'

The first response should contain an empty items array and a count of zero. Add an item:

curl -i -X POST http://127.0.0.1:3000/api/notes \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: YOUR_LOCAL_KEY' \
  -d '{"title":"Deploy my first REST API"}'

A successful POST returns 201 Created and an automatically generated note ID. Reading /api/notes again returns that note. To delete it, substitute the exact returned ID:

curl -i -X DELETE \
  http://127.0.0.1:3000/api/notes/NOTE_ID \
  -H 'x-api-key: YOUR_LOCAL_KEY'

The delete route returns a JSON confirmation. If you restart the server and list notes again, the collection will be empty. This is expected: we’re demonstrating HTTP contracts, not durable persistence.

Test failures on purpose

An API that succeeds only under ideal conditions is not ready for real clients. Run these deliberate checks:

RequestExpected codeWhat you learn
GET /healthz200The HTTP process responds
GET /api/notes without a key401Protected routes require credentials
POST /api/notes with malformed JSON400Invalid payloads are rejected
POST /api/notes with text/plain415Content type is checked
POST /api/notes with an empty title422Data is validated
Unsupported HTTP method405The route exposes an explicit method contract
Unknown URL404Missing routes are not confused with authentication

These cases matter because clients rely on status codes to decide whether to retry, correct input, log in or display an error. A 500 should be reserved for an unexpected server-side failure, not used for every invalid request.

Step 5: Prepare the project for Volyx or another managed host

Now that local tests pass, package the project without .env, temporary logs or hidden development credentials. Keep server.mjs, package.json, and .env.example. Before uploading, review the files for hardcoded keys and ensure the expected Node.js runtime is available. Volyx offers different Node versions, but what is selectable for your specific hosting allocation must be checked from its runtime/startup controls.

A practical Volyx deployment checklist:

  1. Sign in at Volyx and open your server dashboard.
  2. Choose a compatible Node.js server or app environment. Do not assume a Discord-bot container automatically includes public API hosting.
  3. Upload the source files using the Files interface or an available supported transfer method.
  4. Configure API_KEY privately and set the correct PORT and HOST for the allocation. Use the panel’s documented secrets/configuration mechanism where available.
  5. Set the main entrypoint to server.mjs if required, and a startup command such as node server.mjs or npm start according to the server’s startup configuration.
  6. Start the process and open Console to confirm it stays running and logs the expected listening address.
  7. Use the provider-supported way to test the allocated port. If the host offers a public HTTPS route, attach it and verify requests from outside the allocation.
  8. If no public ingress is offered, stop here for the public API use case or use a service that explicitly supports HTTP deployments. Your program may still be useful internally, but advertising a public URL would be misleading.

Volyx Coins note: A hosting service may use resources and Coins or expire unless renewed. That is an availability consideration separate from whether the Node app works. Your API will not answer requests if the underlying allocation is stopped or suspended. Do not promise “always online” without verifying the plan and its renewal conditions.

Step 6: Set up a safe HTTPS entry point

For an API that accepts secret-bearing headers, plain HTTP on the public internet is not sufficient. Traffic from the client to the public endpoint must use HTTPS, and the proxy-to-application link needs an appropriate trust boundary. When using a service that manages TLS automatically, follow its domain or ingress setup guide. When you control your own VPS and proxy, you might route a hostname such as api.example.com through Nginx to the loopback API port.

This is a conceptual proxy example, not a paste-and-run modification for the shared Volyx server:

# Illustrative HTTPS server block only; TLS configuration omitted.
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_connect_timeout 5s;
    proxy_read_timeout 30s;
}

A complete Nginx deployment also needs a correctly configured HTTPS server block, a valid certificate, firewall rules, secure headers, and a verified upstream. Do not apply that snippet blindly on a live shared host or to Volyx Nginx unless you administer the server and know which domain and application port you are changing. For many providers the right action is simply enabling the host’s built-in public-web-service feature.

After connecting a genuine HTTPS endpoint, test it independently of the panel:

curl -i https://api.example.com/healthz

You need a real 200 from that publicly reachable domain. Check the exact hostname, route, certificate validity and that the response comes from your Node app, not from an unrelated default website. Never bypass certificate validation just to make a security test look successful.

Step 7: Connect a real client without leaking secrets

Once the public API responds, a backend service can call protected routes. For example, another Node server may read its API key from a private environment variable and send a request using fetch:

const response = await fetch('https://api.example.com/api/notes', {
  headers: {
    'x-api-key': process.env.API_KEY
  }
});

if (!response.ok) {
  throw new Error(`Upstream API returned HTTP ${response.status}`);
}

const data = await response.json();
console.log('Notes:', data.count);

That example belongs in a trusted server-side client, not a public browser bundle. If you embed API_KEY in frontend JavaScript, every visitor can extract it. For browser-facing applications, use an authentication design appropriate to your users: session cookies, scoped access tokens, an authorized backend facade or another proper identity system.

Also remember that setting Access-Control-Allow-Origin: * does not make your API safe. CORS is a browser policy that controls reading cross-origin responses; it is not authentication. Avoid broad CORS rules unless the application actually requires them and has suitable authorization.

Volyx deployment compared with a generic VPS and managed web app

Before selecting a host, compare the actual capabilities required by your workload rather than the biggest RAM number on a marketing page.

Deployment optionHow you start the processPublic HTTPS APIMain responsibility
Volyx Node.js allocationPanel Files, Startup and Console, when offered for your serverVerify per allocation; not implied by a running bot/containerMatch runtime, port, Coins and available inbound routing
Self-managed VPSNode process plus a service manager such as systemdPossible if you configure DNS, TLS, firewall and reverse proxyYou maintain the server, security and updates
Managed web-app platformGit or package deployment using provider-specified start commandOften provided by the web-service product; confirm the planPlatform handles ingress; you handle app security and limits
Local machinenode --env-file=.env server.mjsNo public HTTPS endpoint by defaultBest for isolated development and testing

This is a deployment model comparison, not a claim that one vendor has a particular amount of RAM, zero downtime or unrestricted free hosting. Pricing, resource limits, sleep/idle rules and ingress features can change and should be verified at signup.

What changes when you add PostgreSQL?

A production API usually needs a real data layer. If notes must survive a restart, you might choose PostgreSQL, which can be managed separately and accessed using a private connection string. The application would read DATABASE_URL from its environment, establish a connection pool, create explicit schemas and perform parameterized queries. You would also add migrations, backups, access-control logic and monitoring.

Don’t simply replace the Map() in this example with synchronous writes to a JSON file on a shared hosting filesystem. Parallel requests, crashes and partial writes can corrupt that file. If you use SQLite for a single-instance app, learn its durability and concurrency limits; for a service expected to scale to multiple processes, plan your datastore deliberately.

If your Volyx server offers databases, examine which engine and network access are available in your account. A PostgreSQL option appearing in a general product interface does not guarantee every server allocation includes a database automatically.

Security checklist before your first public request

Before sharing your API URL, audit these decisions:

  • Secrets: API keys and database credentials are environment-managed and never committed or printed to logs. Rotate immediately if exposed.
  • HTTPS: Every public credential-bearing request travels through a trusted HTTPS endpoint, with a valid certificate.
  • Authorization: Credentials are checked on each protected operation. A single shared key is acceptable for this teaching demo, not for sensitive multi-user operations.
  • Validation: JSON format, title length, body size, method and allowed paths are checked. Avoid sending full stack traces to clients.
  • Limits: Add real request rate limiting and resource controls at a trusted ingress or application layer. A single-process capacity cap is not comprehensive rate limiting.
  • CORS: Only enable cross-origin browser access where needed; CORS is not a substitute for authentication.
  • Availability: Know how the server restarts, when the allocation can expire or suspend, and where to read logs.
  • Persistence: Use a database when a restart must not lose user data. Back up durable content.
  • Updates: Monitor Node.js security releases and dependencies. Pin or test runtime upgrades before changing production.
  • Monitoring: Keep a minimal health endpoint and external availability checks; do not return confidential configuration or secrets in health responses.

For additional background, the OWASP REST Security Cheat Sheet explains secure HTTP methods, authentication, HTTPS, response codes and why exposed keys should never appear in URLs.

Troubleshooting: 12 problems that stop Node.js APIs

A useful log tells you where the failure occurred. Always separate process startup from networking and public HTTPS behavior before changing code at random.

SymptomLikely reasonWhat to check first
node: command not foundRuntime is missing or startup environment is wrongNode version and executable path supplied by your provider
SyntaxError: Cannot use import statement outside a moduleModule format mismatch.mjs file extension or "type": "module"
API_KEY error on startupNo secret supplied or value is too shortHosting configuration; verify presence without printing it
EADDRINUSEAnother process already listens on the portActual allocation and competing service
EACCES while bindingPort or interface permission issueUse provider-allocated unprivileged port
Server starts, external request times outMissing ingress, firewall or wrong bind addressInternal reachability, public route and proxy connectivity
502 Bad GatewayReverse proxy cannot reach healthy upstreamProxy upstream port, app health and process restarts
404 Not FoundWrong path or request routed to another siteHostname, route, and whether your app received the request
401 API key required or invalidHeader missing, typo or rotated keySend x-api-key from trusted client over HTTPS
415 Content-Type must be application/jsonPOST uses wrong formatSet JSON content type and send valid JSON
413 Request body too largePayload exceeds 16 KiB demo limitReduce payload or design intentional upload endpoint
Notes vanish after a restartApp uses in-memory storageAdd a database before real-world use

Original decision-flow illustration for diagnosing local process, proxy, HTTPS and API-route failures

Diagnose a 404 without guessing

The URL alone cannot tell you which component sent the 404. Try the /healthz route locally against the assigned port, then request the equivalent path on the public domain. If the internal route returns 200 but the public domain returns 404, investigate domain routing or the reverse proxy. If both return 404, inspect your Node router and request method. If only protected routes return 401, your network path is probably functioning and credentials are the next issue.

Diagnose EADDRINUSE

An EADDRINUSE exception means Node cannot bind the requested address and port because something else is already listening there. On your own VPS, review the service binding; on managed hosting, inspect the configured port and running processes using the panel’s permitted tools. Do not kill unrelated services on a shared host. Avoid hardcoding port 3000 in production if your hosting allocation assigns a different value.

Diagnose HTTPS failures

A certificate error can happen even when Node responds perfectly at its internal address. Check domain DNS, active certificate, SNI hostname and proxy routing. Don’t treat curl -k as a successful HTTPS validation for readers: it deliberately bypasses certificate verification and hides an important class of security failure.

Diagnose an API that appears healthy but loses data

/healthz only proves that the process accepts a request. It does not show whether a database connection is healthy or whether data is durable. In this tutorial’s in-memory API, losing notes after a restart is intentional. In a real app, use an operational readiness check that verifies important dependencies without revealing credentials or internal system details to the public.

How to make the project production-ready

This is the point where a tutorial ends and real application engineering begins. If you want to serve users or customer data, you should make several upgrades deliberately.

First, separate identities. A single API key gives every authorized caller the same access to every note. In a multi-user product, authenticate individual users and enforce which records each user may read or change. Never assume that knowing a note ID grants permission to delete it.

Second, add persistence. Store notes in a database and define migrations. Decide what happens if two requests update the same record. Include backup and restore procedures, not just a dashboard that says “database connected.”

Third, add sensible operational controls. Use real rate limits, logs with redacted secrets, request IDs, an error budget, and alerts when the app repeatedly restarts. Limit memory use and request sizes; consider graceful shutdown behavior so deployments do not drop all in-flight requests.

Finally, document your API contract. Describe request JSON, response fields, status codes, and authentication. As your API grows, consider an OpenAPI specification and tests for every endpoint. Releasing a public interface without a stable contract makes clients harder to maintain.

Frequently asked questions

1. Can I host a Node.js REST API for free in 2026?

Possibly. Some services let you run small Node.js processes without an upfront hosting fee or through earned credits, but free plans often impose resource, network, availability or renewal limits. Public HTTP ingress is a separate requirement; check that your chosen service actually supports HTTPS requests to your app before choosing it for an API.

2. Can Volyx host a REST API?

Volyx supports Node.js workloads through its hosting ecosystem. Whether a particular allocation can receive public HTTPS requests must be confirmed through that allocation’s Network settings and any provider-supported domain or reverse-proxy functionality. Running node server.mjs alone does not create a public API URL.

3. Do I need Express to make a Node.js API?

No. Node includes node:http, which is enough for the small tutorial API built here. Frameworks such as Express can help organize middleware, routing, validation and larger applications, but they are optional. Choose a framework when its abstractions genuinely help your project.

4. What is the best Node.js version to deploy?

Use a maintained Node.js release compatible with your code and dependencies, and test on that exact release before production. This tutorial targets Node.js 22 or newer. A provider offering several versions does not mean every version is equally appropriate for every project.

5. What is process.env in Node.js?

It is the standard way Node programs access environment variables inherited from their process environment. These variables can hold configuration such as ports and connection strings. They are not magically encrypted; you still need proper secret storage, access control and log hygiene.

6. Should I upload my .env file to hosting?

Prefer the hosting provider’s secure environment-variable or secrets interface. Do not upload a real .env into a public web directory, commit it to Git, or publish it inside a downloadable archive. A harmless .env.example is useful for documenting the required variable names.

7. Why does my API work locally but not from the internet?

It may be listening only on 127.0.0.1, the provider may not expose incoming HTTP ports, the reverse proxy may target the wrong allocation, or DNS/TLS may be incorrect. Test local health, upstream routing and public HTTPS separately to isolate the cause.

8. Is 0.0.0.0 always the correct HOST?

No. It binds to all available interfaces. That may be necessary for an app behind a container ingress, but it can also broaden exposure if you manage a public interface directly. Use 127.0.0.1 for local development and follow the trusted hosting/proxy topology for deployment.

9. Why do requests return 401 Unauthorized?

A protected request did not include the expected x-api-key value, or its value was wrong. Verify that your client sends the header through HTTPS and that the server has the intended current key. Avoid troubleshooting by printing secrets to logs.

10. How can I save notes after a restart?

Use a durable database. The downloadable Notes example stores records in an in-memory JavaScript Map as a learning exercise. Add PostgreSQL or another appropriate datastore, migrations and backups before storing anything you cannot afford to lose.

11. Is an API key enough to secure a production API?

Not for most sensitive or multi-user APIs. A key can be leaked and often identifies only an application, not an individual user. Use HTTPS, least-privilege authorization, rotation, limits, monitoring and authentication appropriate to the data and actions involved.

12. Should I put an API key in a browser app?

No shared secret should be embedded in frontend JavaScript distributed to visitors. Users can inspect browser code and network requests. Use a trusted backend or an authentication design specifically intended for untrusted browser clients.

13. Does an API need a database?

Not always. A health endpoint or stateless transformation service may not need persistent storage. An API that creates customer records, uploads, paid accounts or durable notes normally does. The data model should follow the real product need, not the simplicity of an introductory demo.

14. What causes a 502 error after deployment?

Usually the public proxy cannot reach a healthy upstream application. Check whether the Node process is running, what address and port it listens on, and whether the proxy has network access to that endpoint. Avoid guessing that the problem is always SSL or Node syntax.

Final deployment checklist

Before calling the tutorial finished, answer each question with evidence: does the server start with your chosen Node version? Does /healthz return 200 locally? Does missing authentication return 401 on protected routes? Can a correct client create and delete a note? Does the public HTTPS URL work with a valid certificate? Are real credentials absent from code and logs? And do you understand which data vanishes when the process restarts?

If all you need is a bot that makes outbound requests, your hosting choice may be much simpler. If you need a publicly reachable REST API, select an allocation and network setup that explicitly supports incoming HTTPS traffic. That distinction will save you more debugging time than changing frameworks.

Ready to build on Volyx? Explore Volyx hosting, learn more in the Volyx documentation, and continue with our related guides: hosting a Discord bot for free, fixing bot startup errors.

Sources and further reading

Keep learning.

Explore more in-depth articles with code, visuals, and practical walkthroughs.

Browse all articles ↗