Use a git-hook to deploy your app

There are a lot of ways to deploy an app to a server, here is a simple one that I often use. This can be a bit confusing if you are not familiar with Git but I promise it’s the easiest way!

It works like this: you create an empty git repository on the server and you push the branch you want to this reposity from your development machine. The repository on the server has a little script (hook) that puts the files in the right directory (‘rails_project’) and runs all the bundle commands. You end up with 2 directories: the bare repository and the ‘checkout’ with the project.

1. Create the bare repository on the server

Login to the server with the user account you want to use to run the application and create the bare repository in the home directory.

or as a oneliner:

You can’t really interact with a bare repository the way you do with a normal repository. But you can push to it and let it automatically run hooks on the server. That’s enough for this setup.

We also need a directory for the checkout, let’s create that as well. I use a generic name for the checkout so I don’t have to change my scripts on every server. I like ‘rails_project’ or just ‘checkout’.

2. Install the commit hook (script)

The application will not run out of the bare repository directory. That’s just where we push the code to. The post-receive hook will check out the code from the bare repository to the ‘rails_project’ directory.

Go back to your home directory with ‘cd’ and edit the post-receive hook:

We need to add a command to do the checkout and run bundle install for us. We’ll add more functionality later.

This will check out the code in the bare repository to the directory ‘rails_project’ and run bundle install in it. Your git client on your machine will show you the output generated by this script after the usual notifications.

And give this post-receive hook enough permissions to run:

 

3. Let’s add the remote and push something

To add the bare-repository on the server as a remote to your local git repository use:

You have to run this command on your development machine, not the server. The ‘newserver’ is just the name of the remote, you can call it whatever you like. I often have ‘staging’ or ‘production’.

And push the master branch to the server. Again, newserver is the name of the remote and master is the name of the branch you want to push to it.

You will see the output of the post-receive hook in your terminal or Git client. To push the same code again if something was wrong on the server create an empty commit and push again.

4. Improvements and troubleshooting

If you use RVM the bundle install part won’t work. You have to use the rvm bundle wrapper like this:

There is no rollback option like with capistrano in with this deployment method but it’s easy to add a database backup to the script with:

And you can login with ssh and migrate your database by hand, but it’s much easier to add it to the post-receive hook. Same for assets:precompile

Touch restart.txt to automatically restart your rails app if you use Passenger:

And if your script generates a lot of output, you might want to add an error notification in case something goes wrong. Add this block to the top of the hook:

and add  || exit_with_error after each command you want to be notified about. For example:

 

That’s all. Let me know if you have any questions about this method or found any mistakes. You can email me on info@runrails.com or Tweet to me at @runrails.com

One thought on “Use a git-hook to deploy your app”

Comments are closed.