If you’re hosting your Node.js application on a cPanel-based server, you can automate deployments using GitHub Actions.
This guide walks you through setting up a simple, production-ready CI/CD pipeline that automatically deploys your code and restarts the app on every push to the main branch.
🧩 Why Use CI/CD with cPanel?
Traditionally, developers log in to cPanel, upload updated files, and manually click the Restart button after every change.
That approach is slow, repetitive, and error-prone.
By integrating GitHub Actions, you can:
- Deploy new code automatically on every push.
- Run builds and dependency installations remotely.
- Restart your Node.js app automatically using Passenger (the process manager used by cPanel for Node.js apps).
🛠️ Prerequisites
Before you begin, make sure you have:
- A Node.js app hosted on cPanel (e.g.,
api.exampledomain.com). - SSH access enabled on your cPanel account.
- Your app is already running via Passenger (cPanel’s Node.js app handler).
- A GitHub repository containing your app source code.
🔑 1. Store Your cPanel Credentials as GitHub Secrets
In your GitHub repository:
- Go to Settings → Secrets and variables → Actions → New repository secret.
- Add the following secrets:
| Secret Name | Description |
|---|---|
SSH_HOST |
Your cPanel server IP or domain |
SSH_USERNAME |
Your cPanel username (e.g. webhost123) |
SSH_PASSWORD |
Your cPanel account password |
SSH_PORT |
Usually 22
|
⚙️ 2. Create the GitHub Actions Workflow
Inside your repository, create a new file:
.github/workflows/deploy.yml
Paste the following configuration:
name: Deploy Node.js App to cPanel
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 🧩 Checkout code
uses: actions/checkout@v3
- name: ⚙️ Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '22'
- name: 📦 Install dependencies
run: npm install
- name: 🏗️ Build (if needed)
run: npm run build || echo "No build script"
- name: 🚀 Deploy to cPanel via SSH
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
source: "., !.git"
target: "/home/webhost123/api.exampledomain.com"
strip_components: 1
- name: 🔁 Restart Node.js App via Passenger
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
script: |
echo "🔧 Activating virtual environment..."
source /home/webhost123/nodevenv/api.exampledomain.com/22/bin/activate
echo "📂 Navigating to app directory..."
cd /home/webhost123/api.exampledomain.com
echo "📦 Updating dependencies..."
npm update
echo "✅ Node version: $(node --version)"
echo "✅ NPM version: $(npm --version)"
echo "♻️ Restarting Node.js app via Passenger..."
mkdir -p tmp && touch tmp/restart.txt
echo "✅ Application deployed and restarted successfully!"
- name: ✅ Deployment Success
run: echo "🎉 Deployment to api.exampledomain.com was successful!"
🧠 How It Works
Trigger:
The workflow runs automatically whenever code is pushed to themainbranch.Build and Upload:
GitHub Actions installs dependencies and uploads the latest build to your cPanel app directory via SSH.Virtual Environment Activation:
The workflow activates your Node.js virtual environment created by cPanel (usually located in/home/USERNAME/nodevenv/APP_FOLDER/22/bin/activate).Passenger Restart:
The command
mkdir -p tmp && touch tmp/restart.txt
signals Passenger to gracefully restart your app without downtime.
🧩 Folder Structure Example
On your cPanel server, the structure typically looks like:
/home/webhost123/
│
├── nodevenv/
│ └── api.exampledomain.com/
│ └── 22/
│ ├── bin/
│ └── lib/
│
└── api.exampledomain.com/
├── index.js
├── package.json
└── tmp/
The tmp/restart.txt file is automatically created or updated by your pipeline to restart Passenger.
🧩 Common Issues
| Issue | Cause | Fix |
|---|---|---|
❌ pm2: command not found
|
cPanel uses Passenger, not PM2 | Replace PM2 commands with the Passenger restart method |
| ❌ App doesn’t restart | Missing tmp folder |
Add mkdir -p tmp && touch tmp/restart.txt
|
| ⚠️ SSH fails | Wrong credentials or port | Double-check GitHub secrets |
✅ Benefits of This Setup
- No manual uploads or restarts.
- Automatic environment activation.
- Works natively with cPanel Node.js hosting.
- Can be extended for build steps, testing, or notifications.
🎉 Final Thoughts
With this setup, every time you push to your main branch, your Node.js application hosted on cPanel is automatically deployed, updated, and restarted — all without you ever logging into cPanel.
It’s a simple but powerful CI/CD pipeline for small to mid-scale Node.js apps hosted on shared servers.
Top comments (0)