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.
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
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://email@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
git push production
should now be possible.