Introduction
Your application runs as a worker process, which is a command the panel starts, keeps running, and serves on your domain. If the process stops for any reason, the panel starts it again within a few seconds, so you do not need a process manager.
Note: We tested the steps in this guide on a Node.js Premium site. A Node server was started, stopped on purpose, and restarted, then switched to new code and a different Node version.
Uploading Your Code
You may put your code on the site in one of three ways:
- GitHub, so every push deploys. Most applications should use this approach, which is described in Deploying From GitHub.
- SSH:
git cloneyour repository into a folder in the site’s home directory, for example~/app. See how to use SSH. - File manager: upload a zip of the project and extract it into a folder.
Warning: Keep your application out of
public_html. That folder is served to the web as files, which would expose your source code and.envfile.
Installing Dependencies
Over SSH, run the following commands from the folder that holds package.json:
cd ~/app
npm ci
Use npm install if the project has no lockfile. If the shell reports that npm is not found, load the site’s Node first with source ~/.nvm/nvm.sh.
The worker never installs dependencies itself, so run this before the first start and after any change to package.json. If your application has a build step, such as npm run build, run it now as well.
Starting Your Application
Open the site, then Advanced and Worker processes, click Launch, and choose Node.js:
- Version. Choose a numbered long term support release, for example 24.x, or the version your
package.jsonspecifies inengines. Avoid stable, which installed a pre-release build in testing. The first start installs the version for the site, which takes under a minute. - Startup command.
node server.js,npm start, or whatever your application runs with. Use single quotes only, since a double quote breaks the command. - Working directory. The folder holding your code, for example
app. This field cannot be empty. - HTTP proxy. Turn this on and enter the port your application listens on. Leave path empty to serve the application on the whole domain, or set a path such as
apito mount it at/api. Turn on websocket upgrade if your application uses websockets.
Your application must listen on that port on all interfaces:
app.listen(3000, '0.0.0.0');
Once the worker has started, your domain will serve your application.
Environment Configuration
The panel has no environment variable screen. Put your settings in a .env file in the application folder and load it when the application starts. On Node 20.6 and later, no package is needed:
node --env-file=.env server.js
On older versions, use the dotenv package. You should keep .env out of git.
Databases and Redis
Every Node.js Hosting plan includes PostgreSQL, MySQL, and private Redis. Create databases and users in the panel, then connect from your application:
- PostgreSQL: use host
/var/run/postgresqland port5432, with the database name, user, and password from the panel. The path is a socket that your application uses to reach PostgreSQL from inside its container. Do not use127.0.0.1orlocalhost. SSL is not needed, since the connection never leaves the server. - MySQL: use the socket at
/run/mysqld/mysqld.sock. Set the driver’s socket path rather than a host and port. - Redis: enable it for the site in the panel, then connect to
127.0.0.1:6379.
For example, using the pg package:
const pool = new Pool({ host: '/var/run/postgresql', port: 5432, database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD });
Deploying From GitHub
Connect the repository on the site’s GitHub tab as described in how to deploy from GitHub. Each push is cloned into a new folder and ~/deploys/current points at the latest release, so set the worker’s working directory to deploys/current.
Your build script must handle two things:
- Keeping
.envoutside the release. Every release is a fresh clone, so the file lives in~/sharedand is linked into each one. - Restarting the application. A deploy does not restart workers, so the old code keeps running until the worker restarts. The last line of the script stops the application, and the panel starts it again on the new release within a few seconds.
#!/bin/sh
set -e
SHARED=../../shared
mkdir -p $SHARED
if [ ! -f $SHARED/.env ]; then
cp .env.example $SHARED/.env
echo "First deploy: fill in ~/shared/.env, then press Deploy now again."
exit 1
fi
ln -sf $SHARED/.env .env
npm ci
npm run build --if-present
# Stop the running app; the panel restarts it on this release.
pkill -u "$(id -u)" -x node || true
Save this as build.sh in your repository and set the build script to sh build.sh. A failed build leaves the previous release running.
Troubleshooting
If your application does not start, check the following:
- The command. A worker that crashes at startup restarts every few seconds and its log only keeps the latest attempt, so the error may disappear. Over SSH,
cdinto the working directory and run the startup command yourself. - The port. The proxy port and the port in your code must match.
- Other workers. Every worker change restarts every worker on the site, so your application may not respond for a few seconds after you edit one.
- Memory. Each site has its own memory limit, set by the plan, and a build that runs out of memory fails. Run heavy builds in GitHub Actions, then commit the result or download it in the build script.
If you are running several applications, a Go or Rust binary, or a Python script, see how to run Node.js, Go, Rust or any binary.