Setting up 'git push production' for shared hosting

4 minute read

Please note: The following steps worked on a shared server from Guru, but if your hosting provider has a slightly different setup your mileage may vary 😉

Time to move on from FTP?

If you're still updating your website by dragging and dropping files in an FTP client, you might want to think about switching up your workflow.

Pushing code directly to a production server isn't necessarily the slickest solution, but it's still a significant step up from the days of bog-standard FTP.

What follows is a step-by-step walkthrough of my setup.


First, let's get SSH working…

Assuming your hosting provider supports SSH (you may need to ask for it to be enabled), log in to cPanel and find the 'SSH Access' admin page. Click on 'Import Key', then fill in the relevant form fields.

Check that everything's working by running a simple ssh command in your terminal. Amend this to suit your own server login details:

ssh cpanel_username@your_website.com

Next, the Git repo

If everything's gone according to plan, you should've now successfully SSH'd into the root of your server. Let's make a Git directory and then navigate into it:

mkdir your_git_repo.git ; cd your_git_repo.git

Now, let's initiate a new bare Git repository:

git init --bare

Now we have a repo in place, we need to set up a post-receive hook. This is what will duplicate our code into the public_html directory when we push to production:

cd hooks
vim post-receive

In your empty post-receive hook file add the following lines and then save it:

#!/bin/sh
GIT_WORK_TREE=/home/yourhomedir/public_html git checkout -f master

On your server, add this to the .bashrc file:

export PATH=/usr/local/bin:$PATH
umask 022

And in the .bash_profile file, below the # User specific environment and startup programs line, add the following:

export PATH=$PATH:/usr/local/cpanel/3rdparty/bin

And then run:

source ~/.bashrc
source ~/.bash_profile

Back in your local environment…

We now need to add the new 'production' remote to the config file in our local Git directory:

git remote add production ssh://username@your_website.com/home/username/your_git_repo.git

Then, to make sure Git knows the correct location of the hook, run the following two commands:

git config remote.production.receivepack /usr/local/cpanel/3rdparty/bin/git-receive-pack
git config receive.denyCurrentBranch ignore

You should now have something like this in your local Git directory config file:

[remote "production"]
	url = ssh://username@your_website.com/home/username/your_git_repo.git
	fetch = +refs/heads/*:refs/remotes/production/*
	receivepack = /usr/local/cpanel/3rdparty/bin/git-receive-pack

Still with me? Now for the fun bit.

It's now time to see if the magic will "just happen". In your local Git directory, prep your commit and push it to production:

git add .
git commit -m "First push to production"
git push — set-upstream production master

Hopefully that worked?! If it did, the files in your Git directory will have magically appeared in your shared server's public_html directory 🎉

Now you can continue development, stashing your working files in your GitLab/GitHub/Bitbucket repo using git push, and running git push production whenever you're ready to send master to production.