Using “git push” to deploy Ruby applications to your own server

If you’ve used Heroku you’ll be familiar with the convenience of using “git push” to deploy your Ruby application. Here’s how you can do the same on BigV using Dokku – a simple system that allows quick deployment of packaged applications, or “buildpacks”.

Dokku uses software called Buildstep and contains your applications using Docker. That’s a lot of buzzwords to put onto your own server, but we’ll get you from those to pushing your application in about 10 minutes.

In this blog post, we’ll show you how to deploy a simple example application (to make sure everything is working). In our next post, we’ll show you how to deploy a more complex ‘real’ application – the code collaboration platform Gitlab.

For our first post, we’ll use simplest-sinatra-heroku. We’ve chosen this simple example of an existing third party Ruby application because it has few other dependencies, and should work really quickly.

Some basics

We assume you have a Terminal program handy – if you’re using Windows we’d recommend installing Cygwin to and using its terminal to follow this through. Linux and Mac systems have a Terminal program built-in.

If you don’t use SSH very often, you may not have an SSH key handy. This is a really useful alternative to passwords, and means you can log in to new servers very quickly.

It’s simple to create one at your terminal, just run:

ssh-keygen

You can just accept the defaults, and leave the password empty for the purposes of this tutorial. But if that’s interesting you might want to follow github’s slightly more informative guide, or look around for articles on more advanced SSH usage.

Get a virtual machine

Now we create a server. If you’re not already on BigV, you can sign up here in about 2 minutes. You can then jump to the web panel to create a new machine.

Once you’ve got an account it should be as simple as logging in with your single sign on or newly created BigV account, and subsequently hitting the Add Virtual Machine button:

Create the machine with 1 core and 1GiB of RAM, a name of your choice (we’ll be using “dokku”) and Ubuntu 12.04 as your choice of distribution. By default, you’ll receive 25GiB of disc space. So the “new machine” screen looks like this:

(You can also use the command line client if you prefer – instructions here).

Click “Add this VM” and the system will get to work! You should have a new machine, and a root password ready for you:

If you’re curious you can watch the imaging process by clicking the “VNC” button. And once it says “Imaging complete” (after a couple of minutes) you can log in.

Install your SSH key on the remote server to avoid having to re-type your password over and over:

ssh-copy-id root@dokku.default.bytemark.uk0.bigv.io
ssh root@dokku.default.bytemark.uk0.bigv.io

You’ll need to replace the hostname with the one the panel gave you, enter the password once and you won’t need to use it again.

Installing Dokku

You can now start to install Dokku, which is the software to supervise your applications, and allows you to deploy with git. First we need to install Dokku’s (pleasantly minimal) dependencies.

Run this at your new server’s root prompt:

apt-get install -y git make curl software-properties-common python-software-properties sudo

Once those are installed, grab the Dokku repository from github:

git clone https://github.com/progrium/dokku.git

We’ll want to check out a specific version of Dokku that works with the version of Ubuntu that we picked. You do this by running:

cd dokku # to change to the newly cloned dokku directory
git fetch origin
git checkout v0.2.3

And you can check this worked by running:

git status

Which should show:

# Not currently on any branch.
nothing to commit (working directory clean)

This means we’re on the version of Dokku currently suggested for use with Ubuntu 12.04 by its author.

One more command will complete our install, and then we’re on to getting configured and deploying:

make install

This takes around five minutes and will download quite a few other dependencies.

At the end of this process, we will have a new UNIX user on the system called ‘dokku’. Its home directory will be at /home/dokku and it will be the user running our applications.

Configuring Dokku

Dokku has its own system of users which are separated by separate SSH keys. So in the long run you can set up deployment capabilities for lots of people, but for now we’ll reuse the SSH key you’re using as our deployment key.

So if you’ve copied your SSH key earlier, you can simply run this on the server, replacing your_username with your usual UNIX username:

cat /root/.ssh/authorized_keys | sshcommand acl-add dokku your_username

You’ll then see some output a little like this if it went right:

7e:fa:49:78:24:6b:12:52:e0:60:2b:4f:09:62:06:da

This should give you access rights to the running Dokku system.

Adding the first application

This is the part where we add a git repository. This can’t just be any repository, it needs to contain a valid buildpack for your application, the part that interfaces with Dokku.

So we’re going to use the simple example program mentioned earlier before attempting something more substantial.

Back on your local system, where you might want to develop and test, clone the example application’s repository with a command like this (or use your favourite Git front-end):

git clone https://github.com/cluesque/simplest-sinatra-heroku.git

Still on your local machine, go into the repository:

cd simplest-sinatra-heroku

What we do now is set our local git repository up with a new “remote”, a reference to our deployment host. We’ll call the new remote ‘sinatra’. So this comand sets itup:

git remote add sinatra dokku@dokku.default.bytemark.uk0.bigv.io:sinatra

And this command does the push to our new host, which will pick it up as a live deployment:

git push sinatra master

(‘master’ is the git branch that we’re deploying – again this is just an easy default for this tutorial).

You’ll see some fairly long output, like this:

$:~/simplest-sinatra-heroku$ git push sinatra master
 Counting objects: 56, done.
 Delta compression using up to 12 threads.
 Compressing objects: 100% (48/48), done.
 Writing objects: 100% (56/56), 12.02 KiB, done.
 Total 56 (delta 21), reused 0 (delta 0)
 -----> Cleaning up ...
 -----> Building sinatra ...
 remote: warning: You appear to have cloned an empty repository.
 remote: HEAD is now at ca04467... Use the actblue public bignumber.js
 Ruby app detected
 -----> Compiling Ruby/Rack
 -----> Using Ruby version: ruby-2.0.0
 -----> Installing dependencies using 1.5.2
 Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
 The source :rubygems is deprecated because HTTP requests are insecure.
 Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
 Fetching gem metadata from http://rubygems.org/.........
 Fetching additional metadata from http://rubygems.org/..
 Installing multi_json (1.0.4)
 Installing multi_xml (0.4.1)
 Installing rack (1.3.5)
 Installing tilt (1.3.3)
 Using bundler (1.5.2)
 Installing temple (0.3.4)
 Installing httparty (0.8.1)
 Installing rack-protection (1.1.4)
 Installing slim (1.0.4)
 Installing sinatra (1.3.1)
 Installing json (1.6.3)
 Installing redcarpet (2.0.1)
 Your bundle is complete!
 Gems in the groups development and test were not installed.
 It was installed into ./vendor/bundle
 Post-install message from httparty:
 When you HTTParty, you must party hard!
 Bundle completed (23.80s)
 Cleaning up the bundler cache.
 The source :rubygems is deprecated because HTTP requests are insecure.
 Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
 -----> WARNINGS:
 You have not declared a Ruby version in your Gemfile.
 To set your Ruby version add this line to your Gemfile:
 ruby '2.0.0'
 # See https://devcenter.heroku.com/articles/ruby-versions for more information.
 -----> Discovering process types
 Default process types for Ruby -> rake, console, web
 -----> Releasing sinatra ...
 -----> Deploying sinatra ...
 =====> Application deployed:
 http://sinatra.dokku.default.bytemark.uk0.bigv.io
To dokku@dokku.default.bytemark.uk0.bigv.io:sinatra
 * [new branch] master -> master

The first time you do this you might actually get slightly different output suggesting a failure; that’s OK, and if you run the “git push sinatra master” command again it should work on the second attempt.

Checking our work

The example application should now be live! You can check out the Sinatra application’s URLs like so, again replacing “dokku.default.bytemark.uk0.bigv.io” with your server’s hostname:

http://sinatra.dokku.default.bytemark.uk0.bigv.io/hi
http://sinatra.dokku.default.bytemark.uk0.bigv.io/page
...and everything else in app.rb.

This should work with any valid buildpack. Where external services (databases, for instance) are required, you’ll need to specify those in the application repository as usual.

Making Dokku work with your domain

You probably want your Dokku-hosted apps to appear on a more memorable domain. If you have one, and can delegate a wildcard record to your host, you only need to update one file with the domain name. So e.g. if you have example.com as your domain, and you want to find your new app at sinatra.example.com you would simply type this on your server:

echo example.com > /home/dokku/VHOST

That should be all. From now you should be able to add new repositories, and once they’re sent to Dokku, you’ll be able to access them through application-name.example.com.

Part 2: Deploying Gitlab – preparing for a real application

In part 2 of this blog post, we’ll show you how to prepare Dokku for a ‘real’ application – Gitlab – a web based git repository manager that’s often described as a “host your own” Github equivalent. Follow @Bytemark on Twitter to find out when it goes live.