Deploy websites using git
Published on Jan 10, 2014This 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: