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.
mkdir bare-repository cd bare-repository git init --bare
or as a oneliner:
mkdir bare-repository && cd $_ && git init --bare
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’.
mkdir ~/rails_project
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:
nano bare-repository/hooks/post-receive
We need to add a command to do the checkout and run bundle install for us. We’ll add more functionality later.
GIT_WORK_TREE=~/rails_project
git checkout -f cd ~/rails_project
bundle install --without development test
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:
chmod a+x bare-repository/hooks/post-receive
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:
git remote add newserver rails@test.runrails.com:bare-repository
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.
git push newserver master
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.
git commit --allow-empty
git push newserver master
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:
/usr/local/rvm/gems/ruby-2.4.0/wrappers/bundle install --without development test
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:
pg_dump your_db_production > ~/pgdump_before_deploy.sql
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
bundle exec rake db:migrate bundle exec rake assets:precompile
Touch restart.txt to automatically restart your rails app if you use Passenger:
touch ~/rails_project/tmp/restart.txt
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:
#!/bin/bash exit_with_error() { echo "[DEPLOY] !!!!!!!!!!!!!!!!!!!! An error has occurred !!!!!!!!!!!!!!!!!!!!!!!" exit 1 }
and add || exit_with_error after each command you want to be notified about. For example:
bundle exec rake assets:precompile || exit_with_error
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
The post Use a git-hook to deploy your app appeared first on RunRails. Photo by Harvey Enrile on Unsplash.
Top comments (0)