A VPS gives you full control, but most businesses in East Africa already pay for shared hosting with cPanel, and many developers start there too. The good news: if your host has the Setup Node.js App icon in cPanel, you can run Express, Fastify or a Next.js server there, on your own domain, with free SSL.
Below, we deploy a Node.js app on cPanel using a simple Express example. The steps are the same for most Node frameworks.
Before you start
- Search cPanel for Setup Node.js App. If you cannot find it, ask your host to enable it; without it, you need a VPS.
- Decide where the app will live: the main domain, a subdomain such as
api.yourdomain.com, or a path such as/api. - Check that your app runs locally with
npm start.
1. Make the app cPanel-ready
The one change most apps need: listen on the port from the environment.
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello from cPanel'));
// cPanel (Passenger) gives you the port. Never hard-code 3000.
const port = process.env.PORT || 3000;
app.listen(port, () => console.log('Listening on ' + port));
Also make sure package.json lists all dependencies, and that your startup file is CommonJS JavaScript. If your project uses TypeScript or a build step, build locally and upload the compiled output.
2. Upload the files
Create a folder outside public_html, for example /home/USERNAME/myapp, and upload your project with File Manager, FTP or git clone from cPanel’s Terminal or Git Version Control. Do not upload node_modules; you will install them on the server.
myapp/
app.js <- startup file
package.json
.env <- not uploaded to Git
public/ <- static files
stderr.log <- errors appear here
3. Create the application
- Open Setup Node.js App and click Create Application.
- Choose the newest Node.js version available that matches your local version.
- Set Application mode to Production.
- Application root:
myapp(the folder you uploaded). - Application URL: pick the domain or subdomain, and a path if you want one.
- Application startup file:
app.js. - Add your environment variables here, such as database URLs and API keys, instead of shipping a
.envfile. - Click Create.
4. Install dependencies
At the top of the app’s page, cPanel shows a command to enter the app’s virtual environment. Copy it into cPanel’s Terminal, then install:
source /home/USERNAME/nodevenv/myapp/20/bin/activate && cd /home/USERNAME/myapp
npm install --omit=dev
node -e "require('./app')" # quick syntax check, Ctrl+C to stop
You can also click Run NPM Install in the interface, but the Terminal shows you the errors if something fails.
5. Restart and test
Click Restart, then open your application URL. You should see your app. Every time you upload new code or change environment variables, restart the app again.
6. Turn on HTTPS
Go to SSL/TLS Status in cPanel and run AutoSSL for the domain or subdomain. The DNS for the domain must already point to the server. Then redirect HTTP to HTTPS, either in Domains or in your app.
Fixing common problems
- 503 or “Incomplete response received from application”. The app crashed on start. Open
stderr.login the app folder; it almost always names the missing module or the syntax error. - “Cannot find module”. Dependencies were not installed in the virtual environment. Run the install step again from the app’s environment.
- The app works on a path but links break. If you mounted the app at
/api, your routes receive the full path. Prefix your routes or use an Express Router mounted at that path. - Changes do not show. Restart the application; Passenger keeps the old process running until you do.
- The app sleeps and the first request is slow. Shared hosting stops idle apps. That is normal; if you need instant responses or background jobs, move to a VPS.
When cPanel is not enough
Shared hosting suits websites, APIs for small apps, and admin dashboards. It is a poor fit for WebSockets with many connections, long-running background workers, or heavy CPU work. When you hit those limits, a small VPS or a platform such as Railway or Render is the next step, and the same app code will move with almost no changes. If you just need a quick API without a server at all, compare with deploying Node.js on Vercel, and before going live, check our Express API security checklist.




