cPanel Git Version Control: Deploy Your Site Without FTP
If you're still deploying changes by dragging files over FTP or unzipping a fresh export in File Manager, cPanel's Git Version Control feature can save you a lot of that hassle. It lets you push code straight from GitHub, GitLab, or Bitbucket into your hosting account, with an optional deploy script that copies files into your live document root automatically. Here's how to set it up properly, and how to fix it when a deploy silently does nothing.
What cPanel's Git Version Control Feature Actually Does
Under the hood, cPanel just runs a bare Git repository somewhere under your home directory (usually ~/repositories/) and gives you a UI to clone from a remote, pull updates, and run a deploy script. It's not magic — it's a wrapper around commands you could run yourself over SSH, but the UI makes the SSH key setup and the deploy hook a lot less fiddly to get right the first time.
Two things trip people up before they even get to their first deploy: SSH access has to be enabled on the account, and the remote repo needs a key it trusts. Get those two right and the rest is mechanical.
Before You Start: What You Need
- SSH access enabled for the cPanel account (ask your host to turn this on if you don't see a Terminal icon in cPanel).
- A Git repository on GitHub, GitLab, or Bitbucket that you can push to.
- Know which directory should receive the deployed files — usually
public_htmlor an addon domain's document root. - A local Git client on your machine (or you'll be committing straight from cPanel's Terminal, which also works).
Step 1: Generate and Add an SSH Key in cPanel
Go to cPanel → Security → SSH Access → Manage SSH Keys → Generate a New Key. Leave the key size at 4096 bits and set a passphrase if you want an extra layer of protection (you'll need it every time cPanel authorizes the key, so a blank passphrase is fine for most setups). After generating it, click Manage next to the key and authorize it — this adds it to ~/.ssh/authorized_keys on the server side.
Now copy the public key and add it to your Git host as a deploy key:
- GitHub: Repo → Settings → Deploy keys → Add deploy key. Tick "Allow write access" only if cPanel will be pushing back to the repo, which is rare — read-only is enough for pulling deploys.
- GitLab: Repo → Settings → Repository → Deploy Keys.
- Bitbucket: Repo → Repository settings → Access keys.
Skipping this step is the single most common reason the next step fails with a permission error, so don't rush past it.
Step 2: Create the Repository in cPanel
Go to cPanel → Files → Git Version Control → Create. You've got two options:
- Clone a Repository — paste your remote's SSH clone URL (e.g.
git@github.com:yourname/yoursite.git), and set the repository path, something like/home/yourcpuser/repositories/yoursite. - Create a New Repository — useful if you want to start version-controlling an existing site that isn't in Git yet.
Note that the repository path is not your live site — it's a working copy. You still need a way to get files from there into public_html, which is what the next step handles.
Step 3: Set Up .cpanel.yml for Automatic Deployment
When you click "Manage" on a repository, cPanel shows a Pull or Deploy tab. Deploys are driven by a file called .cpanel.yml that lives in the root of your repo. Without it, "Deploy HEAD Commit" just does nothing — this catches a lot of people out on their first attempt.
A minimal example that copies everything into public_html:
---
deployment:
tasks:
- export DEPLOYPATH=/home/yourcpuser/public_html/
- /bin/cp -R * $DEPLOYPATH
For a real project you'll usually want something closer to this, which excludes dev-only files and runs Composer if you're deploying a PHP app:
---
deployment:
tasks:
- export DEPLOYPATH=/home/yourcpuser/public_html/
- /bin/cp -R --parents app/ config/ public/ vendor/ $DEPLOYPATH
- /usr/local/bin/composer install --no-dev --working-dir=$DEPLOYPATH
Commit .cpanel.yml to your repo's root and push it before you try deploying — cPanel reads it from the branch you're deploying, not from a local copy.
Step 4: Deploy and Verify
Back in Git Version Control → Manage → Pull or Deploy, click Update from Remote to pull the latest commits into the bare repo, then Deploy HEAD Commit to run the tasks in .cpanel.yml. Check the on-screen log — it shows the exact commands that ran and their output, so if something failed you'll usually see why right there instead of having to guess.
Confirm the deploy actually landed by checking a file timestamp:
ls -la ~/public_html/ | head
Common Errors and Fixes
| Error / Symptom | Likely Cause | Fix |
|---|---|---|
Permission denied (publickey) on clone |
Deploy key wasn't added, or the wrong key was authorized in cPanel | Re-check Step 1 — the public key must match exactly on both ends, no trailing whitespace |
fatal: destination path already exists and is not an empty directory |
You're cloning into a repo path that already has files | Pick an empty path for the repository, or clone into a temp path and move contents over manually |
| Deploy runs with no errors, but the live site doesn't change | Missing or misconfigured .cpanel.yml, or DEPLOYPATH points to the wrong document root |
Confirm the document root in Domains, and double-check the path in .cpanel.yml matches it exactly |
| Old version keeps showing after deploy | Browser or page cache, not the deploy itself | Hard-refresh, and if you're using a caching plugin or Cloudflare, purge cache after each deploy |
| Composer or npm commands fail during deploy | Binary not on PATH in the restricted deploy shell environment | Use the full binary path (e.g. /usr/local/bin/composer) — check it with which composer over SSH |
Keeping Secrets Out of Your Repo
Never commit wp-config.php, .env, or any file with live database credentials or API keys. Add them to .gitignore and instead keep a template (wp-config-sample.php or .env.example) in the repo, with the real file created once directly on the server and left untouched by deploys. If you've already committed a secret by accident, rotate that credential — removing it from a later commit doesn't remove it from Git history.
Prevention: Keeping Deploys Boring
- Deploy from a dedicated branch (e.g.
mainorproduction) rather than whatever branch you happened to push last. - Test
.cpanel.ymlchanges on a staging subdomain before pointing them at the live site. - Keep a cPanel backup or a tagged Git commit before any deploy that changes the database schema or config structure.
- If multiple people deploy, agree on who runs "Deploy HEAD Commit" and when — two people deploying different commits back-to-back is a classic way to lose a fix.
Wrapping Up
Once the SSH key and .cpanel.yml are right, Git deployment in cPanel turns "upload the new files" into a two-click job with a visible log of exactly what happened. It won't replace a full CI/CD pipeline, but for most WordPress or small PHP projects it's a big step up from manual FTP uploads, and it gives you a real commit history to point to when something breaks.
Frequently asked questions
Do I need SSH access to use Git Version Control in cPanel?
Yes. cPanel's Git feature runs over SSH under the hood, so your hosting account needs SSH access enabled before you can clone a repository or authorize a deploy key. If you don't see a Terminal icon in cPanel, ask your host to enable it.
Why does 'Deploy HEAD Commit' do nothing?
This almost always means there's no .cpanel.yml file in the root of the branch you're deploying, or the file exists but has a syntax error. cPanel silently skips the deploy step without it — check the deploy log in Git Version Control for the exact error.
Can I use Git Version Control with WordPress?
Yes, but keep wp-config.php and the wp-content/uploads folder out of version control. Track your theme and plugin code, use .gitignore for config and media, and let the deploy script copy only the folders you actually want to update.
What's the difference between the repository path and my document root?
The repository path (under ~/repositories/) is just a working copy of your Git history. Your live site lives in public_html or your domain's document root. The .cpanel.yml deploy script is what copies files from one to the other — they are not the same folder.
Is Git Version Control in cPanel a replacement for backups?
No. It tracks code changes, not your database, uploads folder, or server configuration. Keep regular cPanel backups running alongside Git deploys, especially before any deploy that changes the database schema.