DEV Community

Sospeter Mong'are
Sospeter Mong'are

Posted on

How to Set Up a Node.js CI/CD Pipeline on cPanel Using GitHub Actions and Passenger

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:

  1. Go to Settings β†’ Secrets and variables β†’ Actions β†’ New repository secret.
  2. 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
Enter fullscreen mode Exit fullscreen mode

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!"
Enter fullscreen mode Exit fullscreen mode

🧠 How It Works

  1. Trigger:
    The workflow runs automatically whenever code is pushed to the main branch.

  2. Build and Upload:
    GitHub Actions installs dependencies and uploads the latest build to your cPanel app directory via SSH.

  3. 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).

  4. Passenger Restart:
    The command

   mkdir -p tmp && touch tmp/restart.txt
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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)