Run a Node.js application
A Node.js application is a runtime a website can choose, like PHP or a static site. This page gets one running, says exactly where the file must live and why, lists the environment your application is handed, and covers what to read when it will not start.
Before you start
What your application has to do.
- Listen on the port it is given, in
PORT, on the host inHOST. Not a port you chose: the panel allocates one and puts the web server in front of it. - Be a plain file it can run. There is no build step here, so build first and upload the result, or run your build over SFTP before switching the runtime over.
- Keep running. The panel starts your file and keeps it alive; it does not call it per request the way PHP works.
Here is the smallest application that satisfies all three:
import { createServer } from "node:http";
createServer((req, res) => {
res.writeHead(200, { "content-type": "text/plain" });
res.end("hello from " + process.env.NODE_ENV);
}).listen(process.env.PORT, process.env.HOST);
With Express, the same point:
app.listen(process.env.PORT, process.env.HOST);
Step 1
Put the files on the website.
Upload your application to the app directory over SFTP. That folder is the working directory your process runs in, so a relative path in your code resolves from there.
sftp websiteaccount@server.example.com cd app put -r ./dist put package.json
Step 2
Switch the runtime over.
On the website, set the runtime to Node.js, choose a version, and give the entrypoint: the path of the file to run, relative to the website.
Runtime Node.js Version 22 Entrypoint app/server.js
The panel writes a service for it, starts it, and points the web server at it. Your domain and certificate work exactly as they do for any other website.
The fields
What each one means, and what it refuses.
| Field | What it is for | Limits and refusals |
|---|---|---|
| Version | Which Node runs your application. Each website chooses its own. | 20, 22 or 24, and only the ones installed on this server. A version the server does not have is refused on the form rather than failing later. |
| Entrypoint | The file the panel runs to start your application. | Must end .js, .mjs or .cjs. Must be relative and already normalised, so app/server.js and not /app/server.js or ./app/../app/server.js: a path that needs repairing is refused rather than repaired. Letters, digits, dot, dash and underscore only. It must live in app or private and never in the public folder. |
| Environment | Your own variables, for a database address, an API key, a feature flag. | Up to 32 of them. Names up to 64 characters, capital letters, digits and underscore, not starting with a digit. Values up to 2048 characters and no control characters. The names the panel sets itself are refused. |
Why the entrypoint cannot be in the public folder. That folder is what the web server hands out. A file there is downloadable by anybody who guesses its name, and the file that runs your server is the last one you want handed over: it is where the database password usually is. The refusal is not tidiness.
The environment
What your application is handed.
| Variable | Value | Why |
|---|---|---|
PORT | The port allocated to this website | What you must listen on. The web server connects to it. |
HOST | 127.0.0.1 | Listen on loopback only. The internet reaches you through the web server, which holds the certificate. |
NODE_ENV | production | What frameworks read to turn off development behaviour. |
HOME | the website’s private folder | So anything writing to a home directory writes somewhere it owns and the web server will not serve. |
TMPDIR | the website’s tmp folder | Scratch space inside the website rather than a shared one. |
PATH | the chosen Node’s own path | So node and npm are the version this website picked. |
These six are set by the panel and cannot be overridden by your own environment: a website that could set its own PORT or HOME would break the arrangement that makes it reachable. Your variables are written to a separate file the service reads, and the panel sets its own after it, so the ones above always win.
When it exits
It restarts, five times a minute, then stops.
A process that exits is started again after two seconds. If it fails five times inside a minute the panel stops trying and leaves it failed, which it reports rather than hiding.
That bound matters: an application that fails on every start, with no limit on retries, would consume the server forever and take the other websites with it. Five failures in a minute is not a transient fault, it is a broken deployment, and the useful thing then is a clear failure rather than a machine under load.
When it will not start
Where to look.
| What you see | Usually means | What to do |
|---|---|---|
| A gateway error in the browser | Your application is not listening on the port it was given. | Check you used process.env.PORT and process.env.HOST rather than a port of your own. |
| The service shows as failed | It exited five times in a minute. | Read the website’s logs: whatever your application printed as it died is there. |
| Module not found | Dependencies were not uploaded, or were built for another platform. | Install them on the server over SFTP, or upload a node_modules built on Linux. |
| It works then dies under load | It passed the website’s memory limit. | Raise it under Limits, or find what is holding memory. |
Everything your application writes to its output goes to the website’s Logs, so console.log and a stack trace both end up somewhere you can read without a shell.