Skip to main content
Updated: May 17, 2026
Matic Bončina
By Matic BončinaFounder
Review pending
This page walks through deploying an existing Node.js project to cPanel: from code on your laptop to a running app at a public URL. For the underlying tool reference, see Node.js.

Before you begin

  • A Node.js project on your machine with a package.json and an entry file (commonly app.js or server.js).
  • cPanel access on a plan that exposes Setup Node.js App.
  • A domain or subdomain already pointed at the account.
If your project uses a specific framework, the framework-specific guide is shorter:

Deploy Express

REST API on Express.

Deploy Next.js

SSR Next.js with a custom server.

Create the container

1

Open Setup Node.js App

From cPanel home, scroll to Software and click Setup Node.js App.
2

Click Create application

On an empty account the Web applications tab reads “No applications found”, with a Create application button beside it.
3

Fill in the form

  • Node.js version: pick the highest LTS your code supports. The dropdown defaults to 20, which is EOL, so change it to 24 unless a dependency holds you back.
  • Application mode: Production. It starts on Development, which is worth keeping only while you chase a boot error.
  • Application root: a folder under your home directory, e.g. myapp. Created for you if it doesn’t exist.
  • Application URL: the domain dropdown plus an optional path. Use / for the root or /api to mount the app on a sub-path.
  • Application startup file: the file that exports your handler. The field starts empty, so fill it in yourself.
  • Environment variables: add them one at a time with Add variable.
4

Click Create

The management page opens. The Selector scaffolds the application root for you, including a working starter app.js, a public/ directory, and tmp/restart.txt.
The full set of buttons on the management page is covered in the Node.js reference.

Upload your code

Three workflows. Pick whichever fits how your project lives today.
Zip your project locally (skip node_modules and .git), then:
  1. cPanel home → File Manager.
  2. Navigate to the application root you created (e.g. ~/myapp).
  3. Upload the zip, then right-click it and Extract in place.
  4. Delete the zip once the contents are extracted.

Install dependencies

Back on Setup Node.js App, find your app in the list and open it. Click Run NPM Install. cPanel sources the per-app virtualenv, then runs npm install against the package.json in your application root. Big dependency trees (Next.js, Nuxt, Strapi, anything that pulls in sharp) can OOM during install. Run it over SSH instead, with flags that keep the resident set smaller:
PMEM on a shared plan caps around 1 GB. If you keep hitting it, build node_modules on a dev machine and rsync the tree up.

Set environment variables

The Environment variables editor sits below the buttons on the management page. Click Add variable, fill in Name and Value, then Done. Restart for new values to reach the running process. Common ones to set:
Don’t set PORT. Passenger ignores it. It drives the runtime over a Unix socket, not a TCP port. If your code reads process.env.PORT, that’s fine, but the value is irrelevant.
Click Save under the editor, then Restart for the changes to take effect.

Make the entry file Passenger-compatible

Passenger starts your process and hands it each request. It hooks the first http.Server that calls listen() and moves it onto a Unix socket, so an ordinary Express app deploys unchanged:
app.js
Exporting the app instead works too, if that’s how your project is written:
app.js
Guides written for VPS deployment sometimes tell you to delete the listen() call first. Skip that step. The port argument is discarded, and the line does no harm.

Start and verify

1

Restart from the management page

Click Restart. Equivalent to touch ~/myapp/tmp/restart.txt from SSH.
2

Hit the URL

Open the Application URL in a browser. Your app should respond.
3

If it's a 503, the process didn't start

A 503 means the app crashed on boot or never came up. Confirm the Application startup file points at a file that exists, run Run NPM Install, then Restart.

Common issues

The process isn’t running. Check the startup file path, then Run NPM Install and Restart. app.listen() is not the cause: Passenger ignores the port you pass it.
package.json is in the right place, but node_modules was built on a different machine or Node version. Click Run NPM Install so it builds against the per-app env.
Passenger allows 90 seconds for an app to start, then kills the process. Loading a large dataset or running a synchronous DNS lookup on boot is the usual cause.Move that work out of the startup path. The Selector doesn’t write an .htaccess into the application root, so there’s no per-app file to raise the limit in; open a ticket if your app genuinely needs longer.
The application URL is set to a sub-path (/api) but you’re hitting /. Either change the URL in the form, or move your routes so they match the configured path.
PMEM is ~1 GB on shared plans. Run install over SSH with --prefer-offline --no-audit, or build node_modules locally and rsync the directory up.
Saving the editor stores the value but doesn’t reload the process. Hit Restart after every change.

Next

Deploy Express

Wire up an Express API.

Deploy Next.js

Run SSR Next.js behind Passenger.

Need a hand?

Open a ticket

Best for anything that needs an account check or a config change on our end.

Live chat

Faster for quick questions during business hours.