Remote Deployment With Git   Apr 02, 2013

If you've ever wanted a streamlined way to deploy code from your development machine directly to your production machine with just a few commands then git is the way to go. In this post I will explain how to use git on your Mac and a linux server, setup a git repository on both machines and show you the commands necessary to push your development code directly to your production server either via the comand line or by using a GUI tool such as the Github app for Mac.


Preparing the git repo on your Mac

Assuming you already have git installed on your Mac, choose a directory where you wish to host your site's HTML, I chose ~/Sites/example.com/public_html. Open up the Terminal app and enter the following commands:

cd ~/Sites/example.com/public_html
git init
git add .
git commit -a

These commands do the following things:

  • Initialise a git repository in the current directory
  • Add the contents of the current directory to the staging area
  • Do a commit of all files in the staging area


Preparing the git repo on the linux server

Again, assuming you have git installed on the linux server, choose a directory where you'd like to push your Mac's git repository to on the linux server. This is not the directory where you'll serve your web pages or application from but a directory where you'll push your development code to. I chose /home/username/sites/example.com/public_html.git Then execute the following commands at a Terminal connected to the server substituting your chosen directory on the server.

mkdir -p /home/username/sites/example.com/public_html.git
cd /home/username/sites/example.com/public_html.git
git init --bare

This inits a bare git repository in the location specified, ready to receive code pushed from the Mac. A bare repository has no working copy, so you can't edit the files in this repository and it is intended only for sharing the contents of the repo, not modifying them.


Configure the remote repository with git on the Mac

To push code to the remote repository, you need to tell git on the Mac where the remote repo is and how to get there. You do this using the following set of commands on the Mac. This assumes you already have ssh access setup to your remote server using keys rather than passwords, there are lots of guides on the internet on how to do this.

git remote add myserver ssh://example.com/home/username/sites/example.com/public_html.git
git push myserver +master:refs/heads/master

These commands do the following things:

  • Add a remote repo called 'myserver' on server 'example.com' which you access via ssh. It also tells git that the file path on the server is /home/username/sites/example.com/public_html.git
  • Push a version of the local repo to the remote server and creates a new branch there called "master"


So far, I've shown you how to initialise a git repo on your Mac so it's now tracking all the files in the 'public_html' directory, I've also shown how you initialise a blank repo on the server that's ready to receive a pushed branch of code from your Mac. We've pushed the code to the remote repo and it now lives on the server in /home/username/sites/example.com/public_html.git but we don't want to serve our webserver content from some users home directory, so we need to tell git to checkout a copy of the code from the server's repo into the webservers html directory after we've pushed it. This will be explained in the next section.


Configure a post-receive hook on the server

Git allows you to configure hooks to fire off custom scripts when certain actions occur. If our server's git repo is in /home/username/sites/example.com/public_html.git but we want to serve our content from /var/www/html/example.com/public_html then we need a way for git to put code in the webserver directory when we make changes to the repo, this is where post-receive hooks come in. We'll add a post-receive hook on the server that runs a script to checkout a copy of the new code into the webserver's directory every time we push to the server.

Using a Terminal connected to the server, do the following: Create the hook file /home/username/sites/example.com/public_html.git/hooks/post-receive, make it executable with chmod u+x /home/username/sites/example.com/public_html.git/hooks/post-receive and put the following into it:

#!/bin/sh
GIT_WORK_TREE=/var/www/html/example.com/public_html git checkout -f

This tells git that when changes are committed to the repo in /home/username/sites/example.com/public_html.git then it should check out a copy to /var/www/html/example.com/public_html.


Test it out

To try out your new deployment method you only need one command on the Mac as shown below and your committed code changes get pushed to your repo on the server and then checked out to the production directory, making your changes instantly live.

cd ~/Sites/example.com/public_html
git push myserver

No FTP client, no mouse clicks, it just works!

As mentioned at the beginning, you can also set up the Github app on the Mac to review, compare, commit and sync changes on your local repo with your server and once you have the post-receive hook in place, it will deploy your production code at the click of a mouse if you prefer a graphical user interface to the Terminal.


Tags for this post:

 Back