PLAINFINCH learn by building

Deploying from Git to your host

You will be able to set up a host to copy your site files from Git using a .cpanel.yml file.

Why deploy from Git instead of uploading files?

The bike shop's site lives on an ordinary shared host with a control panel, the kind many small businesses already pay for. The old way to update it is to open an FTP client or the file manager and drag files across. Nobody knows which version is live, an upload can fail halfway, and rolling back means finding an old copy on someone's laptop.

Deploying from Git replaces that with a rule: the live site is whatever a specific commit says. You commit and push as usual, the host takes that commit, and a small config file tells it which files to copy where. The history doubles as a deployment log, and undoing a bad update is a revert and another deploy.

Many hosts offer this. The steps below follow the cPanel-style "Git Version Control" feature found on lots of shared hosting, because it is common and its config file is short. Other panels and hosts use different names for the same ideas: a repository on the server, a branch to deploy, and a list of tasks.

What does the host's Git feature do?

The host keeps its own copy of your repository in a folder outside the public web folder, for example /home/spokeshop/repositories/site. That copy is a normal Git repository with a checked-out branch. The public folder, usually public_html, is separate.

Deploying means running the tasks from .cpanel.yml in that server copy. The tasks copy files from the repository into public_html. Keep the repository outside the public folder: that stops the .git folder, with your entire history, from being downloadable by anyone who guesses the address.

In the panel you usually see the repository's path, the checked-out branch, the last commit, and buttons such as "Update from Remote" and "Deploy HEAD Commit". The exact labels differ between hosts and versions, and the ideas stay the same.

What goes in .cpanel.yml?

The file sits at the top level of the repository, is named exactly .cpanel.yml (leading dot, lowercase), and is written in YAML. It holds a deployment: key with a list of tasks:. Each task is a shell command the host runs, in order, from the repository's folder.

The usual pattern sets a variable for the target folder, then copies files into it. export DEPLOYPATH=/home/spokeshop/public_html/ names the folder once, and /bin/cp index.html $DEPLOYPATH copies the home page. Use the full path to commands such as /bin/cp, because the host runs tasks with a minimal environment. Replace spokeshop with your real account name from the panel.

YAML cares about indentation and dashes. Use spaces, never tabs, and line up the dashes under tasks:. A broken file means the deploy fails, and the panel's deployment log shows the error. Copy only what the site needs; there is no reason to copy .cpanel.yml or a README into the public folder.

cat index.html
ls
git status

How does pull deployment from GitHub work?

Pull deployment suits most people: GitHub stays the main copy, and the host fetches from it. In the panel you create a repository by cloning your GitHub URL (a private repository needs an SSH deploy key added to GitHub). From then on, each update is three steps.

First, on your computer, commit and push to GitHub as usual. Second, in the panel, press "Update from Remote"; the host pulls the new commits into its copy. Third, press "Deploy HEAD Commit"; the host runs your .cpanel.yml tasks and the live site changes.

The practice terminal plays the part of your computer and GitHub. It cannot press panel buttons, so the demo stops after the push, which is the last step that depends on you getting Git right. If the push is right, the panel steps almost never fail.

git log --oneline
git status
git push
FigureThe bike shop deploy: git push from your computer to GitHub, Update from Remote pulls into the host's repositories/site folder, then Deploy HEAD Commit runs .cpanel.yml, which copies index.html and style.css into public_html, the live site.The bike shop deploy: git push from your computer to GitHub, Update from Remote pulls into the host's repositories/site folder, then Deploy HEAD Commit runs .cpanel.yml, which copies index.html and style.css into public_html, the live site.
The live site is whatever commit the host last deployed. The host pulls from GitHub into its own repository, then the .cpanel.yml tasks copy index.html and style.css into public_html.

How does push deployment work?

With push deployment, you add the host's repository as a second remote and push straight to it over SSH. The panel shows the clone URL, something like ssh://[email protected]:22/home/spokeshop/repositories/site. Name the remote after its job: git remote add host <url>.

When you run git push host main, the host receives the commits and, if .cpanel.yml is present and valid, runs the deployment tasks automatically. One command updates the live site, which is convenient and also a reason to be careful: a push to host is a publish.

Keep origin pointing at GitHub as the shared backup, and push to origin first. That way GitHub always has at least what the live site has, and a teammate can see exactly what was deployed.

git remote add host ssh://[email protected]:22/home/spokeshop/repositories/site
git remote -v

Why does the host want a clean working tree?

The cPanel Git feature refuses to deploy when the server repository has uncommitted changes, and it requires a valid .cpanel.yml at the top level. The reason is the same one that makes Git deployment worth having: the live site must match a commit exactly. If someone edits a file directly on the server, the deployed site no longer matches any commit, and the next update could overwrite the edit or fail.

The same discipline helps on your side. Run git status before you push something you intend to deploy. Uncommitted edits stay on your laptop; they are not in the push, and they will not be on the site. A clean status means what you tested is what you are shipping.

If you ever find yourself fixing a typo through the host's file manager, copy the fix back into your repository, commit it, and deploy properly. Otherwise the next deploy undoes it.

git status -s
git diff

How do you roll back a bad deploy?

Revert the commit that broke things, push, and deploy again. git revert HEAD adds a commit that undoes the last one, keeping history linear and honest for anyone who has already pulled. The host deploys the revert like any other commit.

Avoid rewinding the branch with reset --hard and a force push. The host's copy and GitHub would disagree with your laptop, and "Update from Remote" may refuse to pull rewritten history. A revert never has that problem.

Small, frequent deploys make rollbacks easy. If each commit changes one thing, reverting one commit removes one problem. A single giant commit that changes every page is much harder to undo without losing the good parts.

git log --oneline -3
git show HEAD

Field notes

  • Deploying from Git replaces dragging files around by hand.
  • The host keeps its own copy of the repository outside the public folder.
  • .cpanel.yml lists the commands that copy files into the public web folder.
  • The host only deploys from a clean, committed working tree.

Easy to get wrong

The host looks for that exact name. Anything else is ignored, and the deploy reports a missing or invalid config.

Direct edits leave the server out of step with every commit and can block the next deploy or be silently overwritten by it.

A repository in the public folder can expose the .git folder, and with it every file you ever committed.

Questions people ask

Do I need GitHub to deploy from Git?

No. With push deployment the host's repository can be your only remote. Having GitHub as well gives you an off-server backup and a place for teammates and pull requests.

Can I deploy a branch other than main?

Yes. The panel lets you choose the checked-out branch, and it deploys whatever that branch holds. Many people keep main as the deployed branch and do work on others.

What about sites that need a build step?

Tasks can run commands, though shared hosts often lack Node or similar tools. The common approach is to build locally or in GitHub Actions and commit or upload the built files.

Where do I see why a deploy failed?

The panel keeps a deployment log for each repository. It shows each task and any error, such as a bad path or a YAML indentation mistake.

Keep going