Sometimes you don't need the complexity of deployment automation tools like
capistrano, mina, or fabric.
At the end of the following steps you'll be able to deploy new code into your
production server atomically.
Setup the remote server
First, you'll need to set-up your remote production server.
local$> ssh user@production-server remote$> sudo adduser git remote$> su git remote$> mkdir ~/my-project.git remote$> cd ~/my-project.git
Create a bare git repository, and customize the deployment script. Use the
editor you are familiar with, such as
remote$> git init --bare remote$> vim hooks/post-receive
The following configuration is pretty straight-forward. You may customize it as
you need. It will create a
my-project/releases/v directory, incrementing the
release at every push received. The current version (
always a symlink to the last release.
#!/bin/bash #~/my-project.git/hooks/post-receive SCRIPT_PATH=$(pwd) GIT_REPO=~/project.git RELEASE_PATH=~/project [[ -f $RELEASE_PATH/release ]] && CURRENT_RELEASE=$(cat $RELEASE_PATH/release) || CURRENT_RELEASE=1 NEXT_RELEASE=$(expr $CURRENT_RELEASE + 1) NEXT_RELEASE_PATH=$RELEASE_PATH/releases/$NEXT_RELEASE CURRENT_SYMLINK=$RELEASE_PATH/current git clone $GIT_REPO $NEXT_RELEASE_PATH # You may customize the post-receive hook in a custom deploy on your # repository at `deploy/post-receive` if [ -f $NEXT_RELEASE_PATH/deploy/post-receive ]; then cd $NEXT_RELEASE_PATH source $NEXT_RELEASE_PATH/deploy/post-receive cd $SCRIPT_PATH fi # Force update of symlink ln -fsn $NEXT_RELEASE_PATH $CURRENT_SYMLINK echo $NEXT_RELEASE > $RELEASE_PATH/release
Don't forget to allow the user to execute the post-receive script:
remote$> chmod +x hooks/post-receive
(optional) Deny normal ssh access to git user
It's recommended that you restrict the git user from having normal
ssh access. To do that you'll need to edit the
remote$> sudo vim /etc/passwd
Search for the
git entry, which will be the last. The git line should look
something like this:
You're done with the remote server.
Play with it!
Now, just add the remote and push your changes.
local$> git remote add production git@production-server:~/my-project.git local$> git push production master