cPanel Git Version Control lets you clone a GitHub/GitLab repository directly onto your hosting and automatically deploy changes on push.
Setting Up Git Version Control
cPanel → Files → Git Version Control → Create.
Clone URL: https://github.com/username/mysite.git
Repository Path: /home/user/public_html
Repository Name: mysite
Auto-Deploy via .cpanel.yml
Create a .cpanel.yml file in the root of the repository:
---
deployment:
tasks:
- export DEPLOYPATH=/home/user/public_html
- /bin/cp -r $SRCDIR/* $DEPLOYPATH
- cd $DEPLOYPATH && composer install --no-dev
- cd $DEPLOYPATH && php artisan migrate --force
Manual Deploy via SSH
# Go to the repository folder
cd ~/repositories/mysite
# Pull changes
git pull origin main
# Update production files
rsync -av --delete ./ ~/public_html/ --exclude='.git'
Webhook for Auto-Deploy from GitHub
<?php
// deploy.php
$secret = 'your_webhook_secret';
$payload = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($_SERVER['HTTP_X_HUB_SIGNATURE_256'], $sig)) {
http_response_code(403);
exit;
}
exec('cd /home/user/public_html && git pull origin main 2>&1', $output);
echo implode("
", $output);
RedirectMatch 404 /\.gitAn Alternative to a Webhook: Deploying via GitHub Actions
If the hosting's firewall blocks inbound webhooks, or the plan does not provide a public IP to receive requests, you can deploy over SSH straight from GitHub Actions — the runner connects to the server itself and pulls the changes on every push to the main branch, with no deploy.php file on the site at all.
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: SSH deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
script: cd ~/public_html && git pull origin main
Common Git Deploy Errors
| Message | Cause |
|---|---|
| fatal: Could not read from remote repository | The hosting's SSH key was never added to GitHub/GitLab, or the private repository is being cloned over HTTPS without an access token |
| error: Your local changes... would be overwritten by merge | Files in the server-side repository were edited manually through File Manager; git pull refuses to overwrite unsaved changes |
| .cpanel.yml tasks do not run on push | Deployment in cPanel Git Version Control is triggered by the "Deploy HEAD Commit" button in the interface, not automatically on push from your local machine — automatic triggering needs a webhook |
| fatal: destination path already exists and is not empty | An attempt to clone the repository directly into public_html, which already contains the hosting's default files (index.html) |
| composer: command not found (in the .cpanel.yml log) | Deployment tasks run with a minimal PATH — you need the full path to the binary, e.g. /opt/cpanel/composer/bin/composer |
When Git Deploy Through cPanel Is Not the Right Tool
- You need CI with tests and linters before deployment — cPanel Git Version Control does not isolate the build from production, .cpanel.yml tasks run directly on the live site
- Several developers work simultaneously through reviewed pull requests — that calls for a full GitFlow, not a direct git pull onto the production branch
- You need a one-click rollback to an arbitrary commit — there is no built-in rollback UI, you would have to run git reset manually over SSH
- The build runs inside a Docker container — shared hosting has no Docker daemon, only the commands available inside jailshell
- You need separate staging and production environments with different variables — cPanel Git Version Control is tied to a single Repository Path per account, with no built-in environment separation
Verifying the Deployment
After a push or a manual pull, confirm the server actually received the expected commit — the details of working with SSH keys and jailshell are covered in the article on SSH access on cPanel hosting, and it is convenient to automate the following steps with a cron job.
# Compare the local HEAD with the HEAD on the server
cd ~/repositories/mysite && git log -1 --oneline
git ls-remote origin HEAD
# Check the modification time of a key file in public_html
ls -la --time-style=full-iso ~/public_html/index.php