I'm trying to set up a server with pure-git workflow similar to heroku. I don't need help setting up git, but for informative purposes, I'm using gitolite. I'd like to (somehow) write custom hooks in the operating system (Ubuntu) of this system so that, when it receives a push on a particular branch, it performs all the operators heroku does (starting Rack, Mongrel, Apache (for static serving pages in my case), etc.
Can someone point me towards a resource to do this or at least get started? A google search didn't really seem to help...
It sounds like you want to execute arbitrary functionality at a certain point in your Git workflow. Git hooks are the way to go.
If you look in any Git repo (inside the .git
folder), you'll see a hooks
folder. Inside it there are a number of example hook files with different names. Based on your explanation above, you want to edit the post-receive
hook file, since that will be called immediately after a new ref has been updated in your remote repo (resulting from a push from a local one). For more info, read the official documentation on hooks or read this perhaps more approachable explanation.
You can put any shell commands you want in a hook file. Change the filename from post-receive.sample
to simply post-receive
, add the commands you need to start Rack, Mongrel, Apache, etc., then make the file executable with a quick chmod +x post-receive
and you're all set.
Have you looked at Capistrano? From wiki:
Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple Domain Specific Language borrowed in part from the tool rake. Rake is similar to make in the C world and allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPNs and firewalls.
Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and originally came bundled with a set of tasks designed for deploying Rails applications. The deployment tasks are now (as of Capistrano 2.0) opt-in and require clients to explicitly put "load ‘deploy’" in their recipes.
It's not based on any sort of commit or post hooks, although I'm sure if you really needed that, then you would be able to find some example recipes to do something like that.
Update: Maybe git-deploy (based on Capistrano) is what you want:
A tool to install useful git hooks on your remote repository to enable push-based, Heroku-like deployment on your host.
I just uncovered https://github.com/mislav/git-deploy, which is EXACTLY what I wanted. I'm going to leave the other answer as "correct" (since it was the best at the time), but I'm using git-deploy now :)
I have a similar setup where the master branch is automatically deployed as staging using capistrano on git push. Production is manually deployed from the production branch.
The setup require that you use set :deploy_via, :remote_cache
in deploy.rb
to have a local cache copy on the server. This is to be able to run capistrano with the latest configuration if is has been changed since last deploy.
post-receive
hook script:
#!/bin/bash
while read oldrev newrev ref
do
if [ "$ref" = "refs/heads/master" ] ; then
echo "Master branch pushed, deploying to staging"
# seams to be set to "." for hooks, unset to make things more normal
unset GIT_DIR
# deploy path, where "current", "releases", "shared" etc are
DEPLOYDIR="/home/user/deploy/staging"
# default path for :deploy_via :remote_cache is shared/cached-copy
cd "$DEPLOYDIR/shared/cached-copy"
# update cache to pushed revision, will be done by capistrano too
git fetch origin && git fetch --tags origin && git reset --hard "$newrev"
# load rvm
source ~/.rvm/scripts/rvm
rvm use 1.9.2
# make sure correct gems are installed
# this will also create a .bundle directory
bundle install --gemfile Gemfile --path "$DEPLOYDIR/shared/bundle" --deployment --without development test
# run capistrano
# if you use deploy:migrations instead of deploy you should probably add
# after "deploy:migrations", "deploy:cleanup"
# to your deploy.rb
bundle exec cap staging deploy:migrations
fi
done
A simpler setup without :remote_cache
is also possible but it will run capistrano with the previous (currently deployed) configuration and seams to be a bit more fragile.
post-receive
hook script:
#!/bin/bash
while read oldrev newrev ref
do
if [ "$ref" = "refs/heads/master" ] ; then
echo "Master branch pushed, deploying to staging"
# seams to be set to "." for hooks, unset to make things more normal
unset GIT_DIR
source ~/.rvm/scripts/rvm
rvm use 1.9.2
cd /home/user/deploy/staging/current && bundle exec cap staging deploy:migrations
fi
done
I recommend checking out GitHub:progrium/dokku, it's based on Docker technology and really easy to setup and use.
If you're also looking for cloud provider, I recommend DigitalOcean since they support Dokku out of the box! Checkout their community documentation for more information.
Your workflow will be very much similar to Heroku: (Full Tutorial)
git remote add myheroku [email protected]:your-app
git push myheroku master
http://your-app.DOMAIN.com
Also if you want to have different sub-domain or full-domain assign to your app, you can install Dokku Domain Plugin and simply do specify domain to your-app: dokku domains:set your-app NEWDOMAIN.com
It's worth mentioning new project called Flynn GitHub: flynn/flynn which comes with more features than Dokku. Read history behind Flynn and Dokku here...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With