BabalCloud Logo
PricingAboutBlog
Log inGet Started
BabalCloud

Empowering businesses with reliable, scalable, and secure cloud hosting solutions. Our infrastructure is designed for performance, uptime, and peace of mind.

Products

  • Pricing
  • Domain Registration
  • Domain Transfer

Company

  • About Us
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 BabalCloud Private Limited. All rights reserved.

Proudly serving developers in Nepal.

Back to blog
Developers

How to Auto-Deploy from GitHub to cPanel with GitHub Actions (2026 Guide)

A complete, copy-paste guide to setting up automatic deployment from GitHub to cPanel shared hosting using GitHub Actions — with working FTP and SSH workflows, secrets setup, and troubleshooting.

BabalCloud TeamJuly 22, 20268 min read

If you host on cPanel and still deploy by dragging files into File Manager or pushing over FTP by hand, every release is a chance to upload the wrong file, forget one, or overwrite something in production. This guide fixes that. By the end you'll have a pipeline where every push to your main branch deploys itself to cPanel automatically — no manual uploads, ever.

We'll cover two proven methods (FTP and SSH/rsync), exactly which secrets to set, and how to handle build steps for frameworks like React, Vue, or Laravel. Everything here is copy-paste ready.

Short on time? BabalCloud sets this entire pipeline up for you automatically — it detects your framework, commits the workflow, and configures SSH keys and secrets on its own. See how it works. This guide is for anyone who wants to wire it up by hand.

What "auto-deploy from GitHub to cPanel" actually means

Auto-deployment means a CI/CD pipeline watches your GitHub repository and, whenever you push code, automatically copies the updated files to your cPanel hosting account. On GitHub, the tool that does this is GitHub Actions — free automation that runs in a workflow file inside your repo. You push to main, GitHub Actions runs, and your live site updates in under a minute with zero manual steps.

There are three common ways to connect the two:

  • FTP/FTPS deployment — simplest, works on every cPanel plan. GitHub Actions uploads changed files over FTP.
  • SSH + rsync — faster and safer for larger sites, but needs SSH access enabled on your host.
  • cPanel's native Git Version Control — cPanel pulls from your repo directly using a .cpanel.yml file (no GitHub Actions needed).

We'll set up the first two, since they cover the most cases.

Before you start: what you'll need

  • A GitHub repository with your website code.
  • A cPanel hosting account (BabalCloud, or any cPanel host).
  • Your FTP credentials — host, username, and password (find them in cPanel under FTP Accounts).
  • The path to your web root — usually public_html/ for your main domain, or public_html/subfolder/ for a subdomain.

If your project needs a build step (React, Vue, Next.js static export, Vite, etc.), you'll also need to know your build command (npm run build) and output folder (dist/, build/, or out/).

Method 1: Deploy over FTP (works on every cPanel plan)

FTP is the most reliable method because every cPanel host supports it. We'll use the popular FTP-Deploy-Action, which only uploads files that actually changed — so deploys stay fast.

Step 1 — Store your FTP credentials as GitHub Secrets

Never put passwords in your workflow file. Instead, go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret, and add three secrets:

Secret nameValue
FTP_SERVERYour FTP host, e.g. ftp.yourdomain.com
FTP_USERNAMEThe FTP account username from cPanel
FTP_PASSWORDThe FTP account password

Step 2 — Add the workflow file

In your repository, create a file at .github/workflows/deploy.yml:

name: Deploy to cPanel
 
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
 
      - name: Sync files to cPanel via FTP
        uses: SamKirkland/[email protected]
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          protocol: ftps
          server-dir: ./public_html/
          exclude: |
            **/.git*
            **/.git*/**
            **/node_modules/**
            .github/**
            README.md

That's the whole thing. Commit and push it to main, then open the Actions tab on GitHub — you'll see the deploy run live. When it finishes, your files are on the server.

A few notes:

  • protocol: ftps uses encrypted FTP. Keep it on if your host supports it (BabalCloud does); switch to ftp only if you hit connection errors.
  • server-dir must end in a slash. Use ./public_html/ for your main domain.
  • The exclude list keeps development files off your server. Add anything else you don't want uploaded.

Step 3 — If your project needs a build step

Static apps built with React, Vue, or Vite ship a compiled folder, not raw source. Build it in the pipeline first, then upload only the output:

name: Build and Deploy to cPanel
 
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
 
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
 
      - name: Install dependencies
        run: npm ci
 
      - name: Build the site
        run: npm run build
 
      - name: Upload build output to cPanel
        uses: SamKirkland/[email protected]
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          protocol: ftps
          local-dir: ./dist/
          server-dir: ./public_html/

Change local-dir to match your framework's output folder — ./build/ for Create React App, ./out/ for a Next.js static export, ./dist/ for Vite.

Method 2: Deploy with SSH and rsync (faster, cleaner)

If your BabalCloud plan has SSH access enabled, rsync is the better option: it transfers only the byte-level differences between files and can delete files on the server that you removed from your repo, keeping the two perfectly in sync.

Step 1 — Create an SSH key pair

On your computer, generate a key dedicated to deployment:

ssh-keygen -t ed25519 -C "github-deploy" -f deploy_key

This creates deploy_key (private) and deploy_key.pub (public). Add the public key to cPanel under SSH Access → Manage SSH Keys → Import Key, then click Authorize.

Step 2 — Add SSH secrets to GitHub

Add these repository secrets:

Secret nameValue
SSH_HOSTYour server hostname or IP
SSH_USERYour cPanel username
SSH_PRIVATE_KEYThe full contents of the deploy_key file

Step 3 — Add the rsync workflow

Create .github/workflows/deploy-ssh.yml:

name: Deploy to cPanel via SSH
 
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
 
      - name: Deploy with rsync over SSH
        uses: burnett01/[email protected]
        with:
          switches: -avzr --delete --exclude='.git' --exclude='node_modules'
          path: ./
          remote_path: /home/${{ secrets.SSH_USER }}/public_html/
          remote_host: ${{ secrets.SSH_HOST }}
          remote_user: ${{ secrets.SSH_USER }}
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

The --delete flag makes the server match your repo exactly. If that feels risky at first, remove it — files will only ever be added or updated, never deleted.

A note for Laravel and PHP apps

Laravel needs a couple of extra steps because its public folder — not the project root — is what the web should serve. The cleanest pattern on cPanel:

  1. Deploy your Laravel project to a folder outside public_html (e.g. /home/username/laravelapp/).
  2. Point public_html at the app's public folder, or edit index.php paths accordingly.
  3. Run composer install --no-dev and php artisan migrate --force after deploy — either over SSH in the workflow, or via cPanel's Terminal.

We cover the full Laravel-on-cPanel setup in a dedicated guide (coming soon). If you're choosing a host for a Laravel project, our hosting plans include the SSH access and PHP version control this workflow needs.

Troubleshooting common problems

The Action fails with "530 Login authentication failed." Your FTP credentials are wrong or the account is locked. Re-check FTP_USERNAME (it's often the full [email protected] form on cPanel) and reset the password in FTP Accounts if needed.

Files upload but the site shows a blank page or old version. You likely deployed to the wrong server-dir. Confirm your web root — it's public_html/ for the primary domain and public_html/subdomain/ (or an addon-domain folder) for others.

FTPS connection times out. Some networks throttle FTPS. Switch protocol: ftps to ftp, or use the SSH method instead, which is more firewall-friendly.

The build step fails with "command not found." Make sure actions/setup-node runs before your build, and that your package.json has a working build script locally first.

Permission denied over SSH. The public key wasn't authorized in cPanel. Return to Manage SSH Keys and click Authorize next to the imported key.

Frequently asked questions

Is GitHub Actions free for this?

Yes. Public repositories get unlimited GitHub Actions minutes, and private repos include a generous free monthly allowance that's more than enough for typical website deploys.

Do I need a VPS, or does shared hosting work?

Shared cPanel hosting works perfectly for FTP deployment. You only need SSH access for the rsync method — and many cPanel shared plans, including BabalCloud's, offer it.

Will this overwrite my database?

No. This pipeline only deploys files. Your MySQL databases are untouched. For schema changes, run migrations separately (see the Laravel note above).

How do I roll back a bad deploy?

Because everything is in Git, you git revert the bad commit and push — the pipeline redeploys the previous working version automatically. This is the biggest advantage over manual FTP.

Can I deploy only when I choose, instead of on every push?

Yes. Change the trigger to workflow_dispatch to add a manual "Run workflow" button, or deploy only from a release branch or tag.

Wrapping up

Once this is in place, your workflow becomes simply: write code, commit, push. GitHub Actions handles the rest, every version is tracked, and rollbacks take seconds. It's the single biggest quality-of-life upgrade you can add to cPanel hosting.

If you'd rather skip the setup entirely, BabalCloud builds this exact pipeline for you the moment you connect a repository — framework detection, workflow file, SSH keys, and secrets all configured automatically. Either way, you never touch File Manager again.

#GitHub Actions#cPanel#CI/CD#Deployment#Web Hosting
Share

On this page

  • What "auto-deploy from GitHub to cPanel" actually means
  • Before you start: what you'll need
  • Method 1: Deploy over FTP (works on every cPanel plan)
  • Step 1 — Store your FTP credentials as GitHub Secrets
  • Step 2 — Add the workflow file
  • Step 3 — If your project needs a build step
  • Method 2: Deploy with SSH and rsync (faster, cleaner)
  • Step 1 — Create an SSH key pair
  • Step 2 — Add SSH secrets to GitHub
  • Step 3 — Add the rsync workflow
  • A note for Laravel and PHP apps
  • Troubleshooting common problems
  • Frequently asked questions
  • Is GitHub Actions free for this?
  • Do I need a VPS, or does shared hosting work?
  • Will this overwrite my database?
  • How do I roll back a bad deploy?
  • Can I deploy only when I choose, instead of on every push?
  • Wrapping up