You can deploy Node.js applications on our Linux shared hosting using the Node.js Selector in cPanel, powered by CloudLinux and Phusion Passenger. Create a subdomain, set up the application, add your code, and run NPM install. The steps below cover a working Express deployment on a dedicated subdomain, plus fixes for the two most common setup errors.
package.json file.npm ci. It is not required for the steps below.We recommend giving each Node.js application its own subdomain. This keeps the application at the root path and avoids the most common routing error (covered in the FAQ below).
node.example.com.nodeapp. This creates /home/<username>/nodeapp.node.example.com) and leave the path blank so the app serves at the root.app.js.Using the cPanel File Manager or SFTP, place these two files in your application root (/home/<username>/nodeapp).
package.json
{
"name": "nodeapp",
"version": "1.0.0",
"main": "app.js",
"dependencies": {
"express": "^4.19.2"
}
}
app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Node OK - running ' + process.version);
});
// Do not hardcode a port. Passenger assigns it automatically.
app.listen();
Important: under the Node.js Selector, Phusion Passenger handles routing and serves your app over ports 80 and 443. Your app must not bind its own port. Use app.listen() with no argument, or read process.env.PORT. A hardcoded value such as app.listen(3000) is the most common reason an app fails to start.
package.json.Open your subdomain in a browser, or check it over SSH:
curl -I https://node.example.com/
curl https://node.example.com/
A working deployment returns 200 with the header x-powered-by: Express, and a body of Node OK - running v22... (or your selected version). The x-powered-by: Express header confirms the request reached your Node application.
If you have SSH access and prefer scripting, you can create the application in one command instead of using Steps 2:
cloudlinux-selector create --json --interpreter nodejs --version 22 \
--app-root nodeapp --domain node.example.com --app-uri /
You can then place your files and run the install from within the application environment.
Usually no. After an operation such as NPM install, the Node.js Selector runs a check that compares the application response before and after. It reports a warning if the return code reads None or if the content type changes, for example from text/html to text/html; charset=utf-8. That change is expected: it means your real application has taken over from the placeholder, and Express adds the charset by default. Confirm your app is fine by loading the subdomain. If it returns your expected response with a 200 status, the warning is cosmetic and can be ignored.
This is Express returning its own 404, which means the request reached your app but no route matched the path. It happens when the application is served under a sub-path (for example /myapp) but the code only defines a root route such as app.get('/', ...). The simplest fix is to serve each application from its own subdomain, as described in Step 1, so the base path is / and standard routes work without adjustment. If you must run under a sub-path, mount your routes on an Express Router at that base path.
Check the application's stderr log, shown as the log path in the Setup Node.js App interface (commonly stderr.log in the application root, or under ~/logs). You can also run the app directly inside its environment over SSH to see the full error. The most common causes are a hardcoded port, a startup file name that does not match the actual entry file, and a dependency that did not install.
Multiple Node.js versions are available from the version dropdown, and each application can run its own version independently of other applications on the account. Select the version your app requires; use the current LTS if you have no specific requirement.
No. The full setup can be done from cPanel using Setup Node.js App and File Manager. SSH is helpful for git-based deployments, running npm ci, and viewing logs, but it is optional.