HostleloBlog
SavedSearch
Visit Hostlelo

Deploy a Site From Git in cPanel With .cpanel.yml

Push to Git and let cPanel copy only the files you name into public_html. Back up, test on a branch, deploy safely and fix a dirty working tree.

The short answer

cPanel's Git Version Control deploys a repository by running the bash commands listed in a .cpanel.yml file at the top of the repo. Name each file and folder to copy into public_html instead of using a wildcard, which cPanel warns could deploy the .git directory. Deployment needs a checked-in .cpanel.yml, at least one branch and a clean working tree, so back up first and test on a branch.

A source folder sends a package through a verification check to a server stack, with a backup cube beside it.
Reading options

On this page

You can deploy a site from Git in cPanel by putting a small file called .cpanel.yml at the top of your repository and letting cPanel's Git Version Control tool run it. That file lists the exact copy commands cPanel should run, so only the files you name land in public_html. You push to Git, cPanel copies, and your live folder stays clean.

Here is the part that surprises people: cPanel's own documentation warns you not to use a wildcard to deploy all files, because it could copy items like the .git directory and "cause serious problems." The safe setup is the one where you spell out every file and folder, and that is what this guide builds.

By the end, you will have a backed-up site, a tested .cpanel.yml, a working deploy, and fixes for when Deploy HEAD Commit refuses to cooperate.

What Git deployment actually is

Git records each saved version of your project as a "commit", a snapshot with a message. A "repository" (or repo) is the folder Git tracks, plus a hidden .git folder holding the history.

Git deployment means the server keeps its own copy of your repository and, when a new commit arrives, runs a script that copies the right files into the folder your visitors see. In cPanel, that folder is usually public_html, and the script is your .cpanel.yml.

Why this matters: cPanel denies public access to .git directories, but notes or config files with passwords get no such protection in public_html.

Before you start

  • You can log in to cPanel for the account that hosts the site.
  • You have an account with a Git host such as GitHub or GitLab, and your site's files are in a repository there (or you are happy to create one).
  • Your plan shows Git Version Control in cPanel. Hosts can switch this feature on or off in WHM » Home » Packages » Feature Manager, so if you cannot see the icon, ask your host.
  • You know whether you have shell access, which means being allowed to type commands on the server. Check for Terminal under cPanel » Home » Advanced » Terminal.
  • You have a fresh backup of public_html, and of the database if the site runs WordPress. Step 1 walks you through it.
  • You accept the risk level: moderate. A wrong path in .cpanel.yml can overwrite live files, which is exactly why we back up and test first.

Heads up: cPanel's docs say that without shell access you can only create, clone, delete and view repositories. Deploying is not on that list, so check with your host before you plan around it.

A made-up example to follow along with

This scenario is invented. Juniper Tea Co. is a small shop with a one-page site: an index.html, a styles.css, and an images folder with a few product photos.

The owner edits on a laptop, keeps the files in a GitHub repository, and once overwrote the live page with an old draft. They want a push, a click, and only the right items in public_html.

The example uses the username exampleuser, the domain example.com and the home folder /home/exampleuser/. Swap in your own.

Set up the repository and the deploy file

Step 1: Back up public_html

Before the first deploy, copy what is live right now, so you can put it back if anything goes wrong.

Open cPanel » Home » Advanced » Terminal. The first time you open it, cPanel shows a warning that commands can make your account unusable, and you click I understand and want to proceed to continue.

Run this command to copy public_html into a dated backup folder in your home directory.

cp -a /home/exampleuser/public_html /home/exampleuser/public_html_backup_2026-11-04

The -a flag tells cp to preserve as much of the original structure and attributes as possible. Afterwards, list the folder to confirm it is there.

ls -la /home/exampleuser/public_html_backup_2026-11-04

You should see the same files as in public_html.

If the site runs WordPress, back up the database too. The simplest route is cPanel's Backup Wizard: click Back Up, choose the partial backup for MySQL databases, then click the database file to download it. The file ends in .sql.

If you prefer Terminal, this command exports one database to a file and prompts you for the password instead of putting it on the command line.

mysqldump -u exampleuser_wp -p exampleuser_wpdb > /home/exampleuser/wpdb_backup_2026-11-04.sql

Download the .sql file to your laptop too, so the backup is not only on the server.

A backup you have never restored is a hope, not a backup. Our guide to backing up a cPanel site with an offsite copy and a test restore shows how to prove yours works.

Step 2: Write a safe .cpanel.yml

Your .cpanel.yml goes in the top-level folder of your repository, next to index.html. YAML is a plain text format that uses indentation for structure, so spaces matter.

Create the file on your laptop with this content, changing exampleuser to your cPanel username and the file names to match your site.

---
deployment:
  tasks:
    - export DEPLOYPATH=/home/exampleuser/public_html/
    - /bin/cp index.html $DEPLOYPATH
    - /bin/cp styles.css $DEPLOYPATH
    - /bin/cp -R images $DEPLOYPATH

Each line starting with a dash under tasks: is one bash command. The export line sets DEPLOYPATH so you type the live folder once, /bin/cp copies single files, and /bin/cp -R copies a whole folder recursively.

Notice there is no * wildcard. Anything not named stays in the repository and never reaches public_html, including .cpanel.yml itself and any notes.

Heads up: these commands only add and overwrite files, and nothing in the file removes old ones. If you remove a photo from the repo, check whether the old copy is still in public_html and delete it yourself.

Comments start with #. Avoid characters that are invalid in YAML, which cPanel warns will break the file.

Step 3: Keep secrets out of the repository

Passwords, API keys, and files like wp-config.php with database credentials belong on the server only, never in Git.

Add a .gitignore file at the top of the repo. It lists files Git should leave untracked, which means Git will not add them to commits.

.env
wp-config.php
notes-private.txt

One catch from the Git manual: .gitignore does not affect files Git already tracks. If a secret is already committed, stop tracking it with this command, then commit the change.

git rm --cached wp-config.php

The file stays on your laptop but leaves the repo from that commit on. Older history still has it, so change any committed password.

Step 4: Commit and push to your Git host

On your laptop, in the project folder, add the new files and commit them.

git add .cpanel.yml .gitignore
git commit -m "Add cPanel deploy file"
git push origin main

Refresh the repository page on your Git host. You should see .cpanel.yml sitting next to index.html at the top level.

Why this matters: cPanel's docs recommend checking .cpanel.yml into the remote repository, not editing it only on the server. If you edit it on the server, you make the server copy "dirty", and deploys stop.

Step 5: Clone the repository in cPanel

Go to cPanel » Home » Files » Git Version Control and click Create.

Turn on the Clone a Repository toggle and paste your repo's address into Clone URL. Use the plain address, such as https://github.com/example/juniper-site.git, never one with a username and password inside it. cPanel rejects those, and you would not want them stored anyway.

Accepted formats are http://, https://, ssh://, git://, or user@host:path, and local server paths are not allowed.

For Repository Path, choose a folder outside public_html, for example /home/exampleuser/repositories/juniper-site. The folder must be empty, or not exist yet, in which case cPanel creates it.

For Repository Name, type something you will recognise, such as juniper-site, then click Create.

The repository list shows the name, path and a progress message while the clone runs.

Heads up: you cannot change a repository's path after you create it, and you cannot put a repo in cPanel-controlled folders such as .ssh, mail, ssl, tmp or cgi-bin. Pick the path carefully the first time.

If your repo is private, cloning over https:// without credentials will not work. cPanel's docs say cloning private repositories takes additional steps, including SSH configuration. Our guide to setting up SSH key login on cPanel hosting covers the key part.

Test on a branch before you touch the live site

Step 6: Create a test branch that deploys to a test folder

A branch is a separate line of commits inside the same repository. On your laptop, create one called deploy-test and switch to it.

git switch -c deploy-test

In this branch only, point DEPLOYPATH at a throwaway subfolder and make sure that folder exists before copying.

---
deployment:
  tasks:
    - export DEPLOYPATH=/home/exampleuser/public_html/deploy-test/
    - /bin/mkdir -p $DEPLOYPATH
    - /bin/cp index.html $DEPLOYPATH
    - /bin/cp styles.css $DEPLOYPATH
    - /bin/cp -R images $DEPLOYPATH

The mkdir -p line creates the folder if it is missing and does nothing if it is already there. Make one harmless change too, such as adding "Test" to the page title in index.html.

Commit and push the branch.

git add .cpanel.yml index.html
git commit -m "Test deploy to subfolder"
git push -u origin deploy-test

Step 7: Deploy the test branch

In cPanel » Home » Files » Git Version Control, click Manage next to your repository. On the Basic Information tab, set Checked-Out Branch to deploy-test and click Update.

Open the Pull or Deploy tab, click Update from Remote, then click Deploy HEAD Commit.

Visit https://example.com/deploy-test/ in your browser. You should see your page with "Test" in the title, while https://example.com/ still shows the untouched live page.

The Last Deployment Information area on that tab should now show the date and the commit you just deployed.

If this worked, the chain is proven without risking the real site. Delete the deploy-test folder in File Manager afterwards.

Step 8: Deploy the real thing

On your laptop, switch back to main. Your main branch still has the .cpanel.yml from Step 2 pointing at public_html.

git switch main

Back in cPanel, set Checked-Out Branch to main, click Update, then on Pull or Deploy click Update from Remote and Deploy HEAD Commit.

Your live site at https://example.com/ should now show the files from main. Juniper Tea Co. now pushes from the laptop, clicks two buttons, and only the named items go live.

Variants

Pull deploy through the cPanel interface

This is what you just did: the repo lives on your Git host, cPanel holds a clone, and you click two buttons to publish. Note that Update from Remote pulls with --ff-only, so it only succeeds if the server copy can move straight forward to match the remote.

Push deploy straight to cPanel

Here, cPanel's own repository is the one you push to. cPanel adds a post-receive hook, which is a script Git runs after it receives a push, to every repository it manages. When you push, that hook runs your .cpanel.yml automatically.

To set it up, create the repo in Git Version Control with Clone a Repository turned off. Then open Manage, copy the Clone URL shown on Basic Information, and add it as a second remote on your laptop.

git remote add cpanel ssh://exampleuser@example.com/home/exampleuser/repositories/juniper-site
git remote -v

The second command should list both origin and cpanel. Use the exact URL cPanel shows you, not the one above, which is only an example.

From then on, this one command pushes and deploys.

git push cpanel main

A push over ssh:// needs working SSH access from your laptop. cPanel's docs do not walk through this remote setup, so treat the URL step as general Git practice, and check with your host. Deploy HEAD Commit works for redeploying without new changes.

Manual path in Terminal

With shell access, you can use Terminal to inspect the server copy with git status and git log, as shown in the checks below. Heads up: cPanel's docs note that repositories added or removed from the command line may not appear correctly in the interface, so create and remove repos through Git Version Control and use Terminal for checks.

Plans without shell access

Without shell access, cPanel's docs say you can only create, clone, delete and view repositories. Deploying is not listed, and private repositories need SSH configuration, so ask your host before relying on it.

If that is your plan, ask your host whether shell access can be enabled. If not, File Manager uploads remain your publishing route.

How to check it worked

Start with a quick header check from your laptop. curl -I fetches only the response headers, which is enough to see the status.

curl -I https://example.com/

The first line should include 200, meaning the page loaded. A 404 or 500 means something is missing or broken, and your Step 1 backup is ready.

Next, confirm your repo files are not exposed. This request should not return 200, because .cpanel.yml was never copied.

curl -I https://example.com/.cpanel.yml

Then open https://example.com/ in a private window to avoid a cached copy and check your latest change is visible.

Finally, confirm the server has the commit you expect. In Terminal, run this in the repository folder.

git log --oneline -n 3

You will see the last three commits, each on one line with a short ID. The top one should match the commit shown under Last Deployment Information and the latest commit on your Git host.

Troubleshooting

Deploy HEAD Commit fails or is unavailable because of a dirty working tree

Symptom: deployment fails, or deployment information disappears from the Pull or Deploy tab. Likely cause: the server copy has uncommitted changes, a "dirty working tree", often from someone editing a file in the repository folder through File Manager.

Fix: open Terminal, go to the repo folder, and see what changed.

cd /home/exampleuser/repositories/juniper-site
git status

Any file listed as modified or untracked is the problem. If the server edit was a mistake, put the tracked file back to its committed version.

git restore index.html

If you want to keep the edit, copy it to your laptop, commit and push it there instead. Run git status again until the tree is clean, then deploy.

The Deploy HEAD Commit button never appears

Symptom: the Pull or Deploy tab shows no deployment section. Likely cause: cPanel needs a valid, checked-in .cpanel.yml at the top level, at least one branch, and a clean working tree, and it hides deployment if any is missing.

Fix: confirm on your Git host that .cpanel.yml is committed at the top of the repo, not in a subfolder. Click Update from Remote, then check git status as above.

Update from Remote fails

Symptom: clicking Update from Remote gives an error instead of pulling. Likely cause: because the pull uses --ff-only, it fails if the server copy has commits the remote does not, or if the remote history was rewritten.

Fix: compare git status and git log --oneline -n 3 on the server with your Git host. If unsure, back up and ask your developer before forcing anything.

Clone fails when you click Create

Symptom: cPanel refuses the clone. Likely causes: the URL has a username or password in it, the Repository Path folder is not empty, or the repo is private and you used an https:// address.

Fix: use a plain URL with an allowed scheme, pick an empty or new folder outside public_html, and for private repos set up SSH first.

SSH host key warning

Symptom: cPanel warns that the remote host's key has changed. Likely cause: the Git host rotated its key, or something is intercepting the connection.

Fix: do not click through. cPanel's docs say a changed key you cannot verify may indicate a man-in-the-middle attack, so check your Git host's official announcements or ask your host before continuing.

Deploy succeeds but the live site looks unchanged

Symptom: Last Deployment Information shows the new commit, but the page looks old. Likely causes: your browser cached the old page, DEPLOYPATH points at the wrong folder, or the file you changed is not listed in .cpanel.yml.

Fix: reload in a private window, check the path against your actual username, and confirm every file you edit has a /bin/cp line.

Deleted files are still live

Symptom: a photo you removed from the repo still loads on the site. Likely cause: the .cpanel.yml above only copies files in, and nothing in it removes old ones.

Fix: remove the old file from public_html with File Manager, after checking your backup has a copy.

Pro tips and security notes

  • Never put a password or token in the Clone URL. Use SSH keys for private repos instead.
  • Keep .env files, wp-config.php and anything with credentials in .gitignore, and keep the real copies only on the server.
  • Do not modify or delete the .git folder inside the server repo. cPanel's docs say this can break the repository beyond repair.
  • Removing a repo from Git Version Control only stops cPanel managing it; the files stay on disk.
  • Add new files to .cpanel.yml when you add them to the site, or they will quietly never deploy.

When to ask your host: if Git Version Control or Terminal is missing, if you see an SSH host key warning you cannot verify, or if a deploy leaves the site returning errors and restoring the backup does not fix it. If you are moving the site to a new server at the same time, plan that separately with our website migration checklist.

The one message worth forwarding

If you want someone else to set this up, send them this.

Hi, I'd like our site deployed from Git using cPanel's Git Version Control and a .cpanel.yml file.

Please:
1. Back up public_html (cp -a to a dated folder) and export the database if there is one.
2. Clone our repo into a folder outside public_html, using a URL with no password in it.
3. Write a .cpanel.yml that copies only named files and folders into public_html, with no wildcard.
4. Keep secrets out of the repo with .gitignore.
5. Test on a branch that deploys to a subfolder before deploying main.
6. Confirm with curl -I that the homepage returns 200 and .cpanel.yml is not reachable.

Can you also confirm our plan includes Git Version Control and shell access? Thanks.

Name every file you deploy, back up first, and test on a branch, and Git deployment in cPanel becomes a calm way to update your site.

Reader questions

Can I browse a repository's commit history inside cPanel?

Yes. In the Git Version Control repository list, the History action opens Gitweb in a new browser tab so you can look through commits.

Can I rename a repository after I create it in cPanel?

You can change the display name on the Basic Information tab and click Update. The repository path itself cannot be changed once the repository exists.

Which characters are not allowed in a cPanel repository path?

The path cannot contain whitespace or characters such as backslash, asterisk, pipe, quotes, angle brackets, ampersand, at sign, dollar sign, brackets, braces, parentheses, semicolon, question mark, colon, equals, percent or hash.

How do I check a Git host's SSH key the first time cPanel connects to it?

When cPanel meets an unregistered host, click Show Host Identification Information to see the key algorithm and its SHA-256 and MD5 fingerprints, compare them with the Git host's published values, then click Save and Continue. cPanel stores the key in the account's known_hosts file.

Can I clone into a subdomain folder that already contains cgi-bin or .well-known?

Not as it stands. Unless you are adding an existing repository, the folder must be empty, so move those items out first or pick a different folder.

What happens to a running Terminal command if I log out of cPanel?

Logging out closes the Terminal sessions after a short delay. Commands still running keep going until their session closes, so let long tasks finish before you log out.

Sources & further reading

  1. cPanel Docs: Guide to Git Deployment
  2. cPanel Docs: Git Version Control
  3. cPanel Docs: Terminal
  4. cPanel Docs: Backup Wizard
  5. MySQL 8.4 Reference Manual: mysqldump
  6. Git documentation: gitignore
  7. Git documentation: git-status
  8. Git documentation: git-restore
  9. curl manual
  10. GNU Coreutils: cp invocation

What changed

Added an original cover illustration, descriptive alt text and matching social image. Article text and publication timing are unchanged.

Originally published . About our editorial updates.

Your next project deserves a better foundation.

Explore hosting built for your next chapter.

Explore hosting

Find your next answer.

Search published guides and articles.

Ctrl / ⌘ K to open · Esc to close