Imagine you develop a website on your development server, store the source code in a remote repository and deploy to a production site. Let’s assume you just finished a new feature. You commit and push the changes to the remote repo. But the glorious days of FTP are long over — how would you utilize git to do the heavy lifting?
We can use git’s hook to automatically deploy changes to the live site, without manually transferring files. Here’s how:
Before we get started, check that your server meets the following requirements:
• Git is installed
• You have shell access
• The PHP exec function is enabled
Most shared web hosting accounts will fail at least one of those requirements, but if you’ve got a VPS or dedicated server then you should be good to go.
For the purposes of this tutorial I’m going to assume that you have a git repo already set up on Bitbucket, and that the repository’s directory structure mirrors your production website. For instance if you want an index.html file deployed to the root level of your website’s public directory, that same file will exist in the repo’s root directory.
First we need to get our goals clarified. There are two types of Git repository that you might want to create on the remote host (server):
Bare repository: If all you need is to push/upload your local changes to the remote without caring so much about the changes made on the server itself, then this is what you need. If you will only be pushing from local and there’s no chance that the content won’t be changed on the server side then choose this type of repository. It is much simpler and easier than maintaining a non-bare repository.
Non-bare repository: When your content is changed on the server side and from local machine/s too, you need a non-bare repository to sync between both (or all) sides.
1. Preparing Git and up SSH keys on local:
Follow the steps where step 4 is optional. After that you are setting up ssh private and public key on your local machine and set the public key to your bitbucket account.
2. Prepare Git on remote:
Git is generally installed on the remote server. If not, you can install it yourself if you are a sys-admin or have required permissions. If you are on a shared server then your best bet is to contact the hosting provider. Don’t worry though, Git is installed on almost all Linux hosting services, though if you do happen to find some hosting provider that do not have Git installed, well, dump them altogether to a nearby dustbin, wash your hands with antiseptic and move on to a decent hosting provider.
Some hosting provider may have Git installed in a different directory than the standard install directory. In this case running git in a terminal for those servers will show error:
ssh -p port email@example.com #Login to remote #or ssh user@domain -p port #change port to actual port number #change user to cpanel username or whatever #change domain.com to your domain name or the actual server name. git git: command not found
This actually means Git is not installed in general case. But some hosting provider installs Git into a different directory which is not in the PATH environment variable. For example, Namecheap shared hosting has Git in /usr/local/cpanel/3rdparty/bin/ folder. So, you should first check how your hosting provider provides git to you. A simple Google search shall bring it out in most cases.
If the previous git command succeeded (it shows help message) you are good to go, or if the git resides in another directory than the standard install directories then all you have to do is add the path to the git binary to PATH environment variable. To do that you need to login to remote host and run these commands:
ssh -p port firstname.lastname@example.org #Login to remote #change port to actual port number #change user to cpanel username or whatever #change domain.com to your domain name or the actual server name. var=/usr/local/cpanel/3rdparty/bin/ #change the path above according to your hosting provider #[[ -d $var ]] && echo "valid" || echo "Not a directory" #comment out the above line and run if you want to check if the path is valid. if ! echo $PATH | grep -q ":$var\([/:]\|$\)"; then echo "export PATH=\$PATH:$var" >> ~/.bashrc && . ~/.bashrc ;fi
That’s it, path is added to the PATH environment variable. You should be able to access git from anywhere in your remote terminal. This is an example output of git command in remote:
server105 ~]$ git usage: git [--version] [--help] [-C ] [-c name=value] [--exec-path[=]] [--html-path] [--man-path] [--info-path] [-p | --paginate | --no-pager] [--no-replace-objects] [--bare] [--git-dir=] [--work-tree=] [--namespace=] <command></command>  <command></command> ...
3. Prepare ssh access on remote:
We need ssh access to the remote host to open a terminal to run git commands. If ssh is not enabled in your remote host, then enable it from your hosting account control panel or contact them to enable ssh. For example, I had to contact through Live Chat with namecheap-support to enable ssh for my hosting account. Most of the time you have some options to enable it yourself from hosting control panel, though it may require some time (72 hrs max depending on your hosting provider) to fully enable ssh on your account.
Each hosting provider may have preferences of their own on which port they intend to allow you to use for ssh. For example, Godaddy allows port: 22, Namecheap allows port: 21098 etc…
You should generally search for the way your hosting provider recommends you to use ssh. Most renowned hosting providers have tutorials/documents available on how to use ssh on their servers. A simple Google search should bring it out.
4.1 Creating a bare repository:
Maintaining a bare repository is simpler than a non-bare repository but for creating we can not say the same. This method has the advantage of keeping the DocumentRoot clean, i.e there will be no .git directory inside DocumentRoot.
Cd public_html mkdir development cd development mkdir ~/Git && cd ~/Git #Git is the directory where we will keep our bare Git repositories. #It's not the DocumentRoot, neither it is a subdir of DocumentRoot. git init --bare myweb.git #creates a bare repo named myweb.git
Now we need a post-receive hook which will checkout the commits after a push. Run these commands on remote-terminal:
cd ~/Git/myweb.git gwt=~/public_html/portfolio/projectfolder #or whatever your DocumentRoot is echo '#!/bin/sh' > hooks/post-receive echo "GIT_WORK_TREE=$gwt git checkout -f" >> hooks/post-receive chmod +x hooks/post-receive #Give execute permission to the script This will create a hooks/post-receive script with execution permission. You can see the content by running cat hooks/post-receive: ]$ cat hooks/post-receive #!/bin/sh GIT_WORK_TREE=/home/user/public_html/portfolio/projectfolder git checkout -f
Now all is set for the remote repository. You won’t have to deal with remote-terminal any more unless you are going to use a non-bare repository too.
5. Creating Git repository on local:
Local git repository is non-bare. So it’s simple, just the git init command inside the folder where you keep your website.
cd ~/projectfolder #or whatever path like /var/www/htdocs or D://xampp/htdocs etc... git init Also add the ssh address of the remote repository: # for bare repo git remote add live ssh://email@example.com:port//home/user/public_html/development/Git/myweb.git # for non-bare repo git remote add live ssh://firstname.lastname@example.org:port/home/user/public_html/development/ #change port to actual port number #change user to cpanel username or whatever #change domain.com to your domain name or the actual server name. #change /home/user/public_html/development/Git/myweb.git to the actual path of the repository in remote #For bare repository, it's the git repo inside ~/Git in remote #For non-bare repo, it's the DocumentRoot of remote
6. Upload the website to remote:
As the website folder itself is a non-bare Git repository we will just add and commit any changes and push the changes to remote.
6.1 Pushing to bare remote repo:
Run these commands on local-terminal:
#assuming we are inside the DocumentRoot #otherwise run the cd command to get to the appropriate dir git add --all && git commit -m your-commit-message git push –all or git push live +master:refs/heads/master git push live
This will upload your site (or changes) to the remote. Changes will be immediately available.