Deploy websites using git

This guide explains how to deploy to a remote server by pushing to a remote git repository which is using a custom post-receive hook to checkout the contents of the repository to the webservers public www root.

The local repository

cd ~/sites
mkdir example.com
cd example.com
git init
> Initialized empty Git repository in /Users/dewey/sites/example.com/.git/

The remote repository

Creating a bare repository

This is the bare repository we are going to push to.

cd ~/git/
mkdir example.com.git && cd example.com.git
git init --bare
> Initialized empty Git repository in /home/user/git/example.com.git/

Adding a custom post-receive hook

This hook will run after each push to the bare repository, checking out the changes to the working tree (Which isn't located in the bare repository because that's how it works). The working tree will have no .git directory (That's how we want it) and will be served by nginx.

vim ~/git/example.com/hooks/post-receive

With this content:

#!/bin/sh
echo "********************"
echo "Post receive hook: Updating website"
echo "********************"

export GIT_WORK_TREE=/home/user/www/example.com
cd $GIT_WORK_TREE
git --work-tree=/usr/share/nginx/www/example.com --git-dir=$HOME/git/example.com.git pull
git --work-tree=/usr/share/nginx/www/example.com --git-dir=$HOME/git/example.com.git checkout master -f

Creating the Work Tree directory

This is the directory where all the files should end up after each push. We will create it within nginx's document root so it'll be served up by the webserver.

cd /usr/share/nginx/www/
mkdir example.com

Permissions

We have to add our regular user to the www-data group which owns the files in nginx's document root so we'll be able to checkout the files.

sudo chown www-data /usr/share/nginx/www/example.com
sudo usermod -a -G www-data user
sudo chgrp -R www-data /usr/share/nginx/www/example.com
sudo chmod -R g+w /usr/share/nginx/www/example.com

Push to remote repository

Now we have to add the remote repository to our local repository so we can push to it.

Our local repository's .git/config should look like this:

[remote "production"]
    url = ssh://user@example.com/~/git/example.com.git
    fetch = +refs/heads/*:refs/remotes/production/*
    gtSSHKey = /Users/user/.ssh/id_rsa
[branch "master"]
    remote = production
    merge = refs/heads/master

Once this is added git remote will show the remote repository:

git remote
> production

Pushing via

git push production

should now be possible.

Resources:

Deploy websites using git
Share this