Deploy Gitlab on your own server using Dokku

Last week, I wrote a tutorial on using “git push” to deploy Ruby applications to your own server using Dokku, a tool that lets you create an environment similar to Heroku on your own server. I demonstrated an example using a simple Ruby app to test the system, which if you haven’t done is well worth running through.

Now we’ve done the example application, it’s time to see another example of Dokku at its best. For this, we’re going to use Gitlab, which is a web based git repository manager – often described as a “host your own” Github equivalent.

We found we had a little trouble with LXC on Ubuntu 12.04’s default kernel (3.2.x), so for this we’re going to upgrade. We picked kernel 3.13, which works nicely and supports LXC better. Fortunately this can be installed from apt, so run:

apt-get install -y linux-image-3.13.0-24-generic

This will prompt you asking what to do about a file called menu.lst – you can install the package maintainer’s version safely since this is a new VM.

After installing, you’ll need to reboot to start using the newer kernel. Run this as root (still on the VM):

shutdown -r now

Now we can wait a minute for the machine to come back up. If you’re using the web panel, you can click on the “VNC” button beside the VM to view the boot process, and tinker with GRUB should you wish to. The machine should come back up with the new kernel without any intervention, though. Once it has booted again and you’ve logged in, check by running:

# uname -r 3.13.0-24-generic

If you see the same output from uname then the system has come up with the newer kernel successfully.

Dokku addons

Dokku has a simple addon system which enables it to support quick administration of things such as local databases and datastores, more in depth configuration of Docker, and so on. We’re going to require a few of these for Gitlab, namely:

dokku-user-env-compile

dokku-rebuild

dokku-redis-plugin

dokku-docker-options

dokku-md-plugin

dokku-supervisord

Installing these is relatively simple; we’ll need to clone some repositories from github into:

/var/lib/dokku/plugins

So do the following as root on your VM:

git clone https://github.com/statianzo/dokku-supervisord.git dokku-supervisord dokku plugins-install git clone https://github.com/musicglue/dokku-user-env-compile.git user-env-compile dokku plugins-install git clone https://github.com/Kloadut/dokku-md-plugin mariadb dokku plugins-install git clone https://github.com/dyson/dokku-docker-options.git docker-options dokku plugins-install git clone https://github.com/luxifer/dokku-redis-plugin redis dokku plugins-install git clone https://github.com/scottatron/dokku-rebuild rebuild dokku plugins-install

This will update apt and install a number of required packages. It takes a little while to run, so go and have a cup of tea or do something else until it comes back.

Once that’s complete, check that the plugins have installed. If you run dokku help you should see:

backup:export [file] Export dokku configuration files backup:import [file] Import dokku configuration files config <app> display the config vars for an app config:get <app> KEY display a config value for an app config:set <app> KEY1=VALUE1 [KEY2=VALUE2 ...] set one or more config vars config:unset <app> KEY1 [KEY2 ...] unset one or more config vars delete <app> Delete an application docker-options:add <app> OPTIONS_STRING add an option string an app docker-options <app> display docker options for an app docker-options:remove <app> OPTIONS_STRING remove an option string from an app help Print the list of commands logs <app> [-t] Show the last logs for an application (-t follows) mariadb:console <app> Open mysql-console to MariaDB container mariadb:create <app> Create a MariaDB container mariadb:delete <app> Delete specified MariaDB container mariadb:dump <app> <file> Dump default db database into file mariadb:info <app> Display database informations mariadb:link <app> <db> Link an app to a MariaDB database mariadb:logs <app> Display last logs from MariaDB container plugins-install Install active plugins plugins Print active plugins rebuild:all Rebuild all apps rebuild <app> Rebuild an app redis:create <app> Create a Redis container redis:delete <app> Delete specified Redis container redis:info <app> Display container informations redis:link <app> <rd> Link an app to a Redis container redis:logs <app> Display last logs from Redis container run <app> <cmd> Run a command in the environment of an application url <app> Show the URL for an application version Print dokku's version

Deploying Gitlab: a more complicated push

Now that your server is prepared, return to your own machine and grab your own copy of the the gitlab repository:

git clone https://github.com/gitlabhq/gitlabhq.git cd gitlabhq

In order for Gitlab to deploy properly to our Dokku host, we need a buildpack which is not part of Gitlab’s own deployment. Thankfully Matthias Rolke (amtrack) has done the hard work for us. Here’s how to add the buildpack to your own copy:

git checkout -b deployment echo -e "https://github.com/amtrack/buildpack-gitlab.git

https://github.com/heroku/heroku-buildpack-ruby.git" > .buildpacks git add .buildpacks git commit -m "prepare for dokku"

Now we’re ready to push, just like before:

As with our example application, we’ll also need to add a remote repository that Dokku will use. So again, add a remote with the application’s name (‘gitlab’ seems the obvious choice, and make sure your replace “dokku.default.bytemark.uk0.bigv.io” with your own server’s name):

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

Push as before, but this time specify a branch:

git push dokku deployment:master

This will fail, and that’s fine. The reason we need to push it is so that Dokku has a copy of our buildpack from which we can instruct it to create databases. This doesn’t happen automatically because it’s bad form to just create & destroy databases without more explicit instruction from the server owner!

So we need to issue instructions to create the databases. Gitlab requires Redis and MariaDB. We’ve already installed the relevant addons to Dokku, so we can run these commands to perform the magic:

dokku mariadb:create gitlab dokku redis:create gitlab

Dokku will now handle creating those databases and Gitlab will be able to use them. Now to set the buildpack URL and the curl timeout:

dokku config:set gitlab BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git dokku config:set gitlab CURL_TIMEOUT=120

Then seed the database and set up some persistent storage:

test -d /opt/gitlab/repositories || sudo mkdir -p /opt/gitlab/repositories test -d /opt/gitlab/.ssh || sudo mkdir -p /opt/gitlab/.ssh dokku docker-options:add gitlab "-v /opt/gitlab/repositories:/home/git/repositories" dokku docker-options:add gitlab "-v /opt/gitlab/.ssh:/home/git/.ssh"

Finally, from your local machine, push again:

git push dokku deployment:master

Seed the database:

dokku run gitlab bundle exec rake db:setup RAILS_ENV=production dokku run gitlab bundle exec rake db:seed_fu RAILS_ENV=production

Set your SMTP credentials:

dokku config:set gitlab SMTP_URL=smtps://<user>: <password>@your-smtp-host.com/?domain=your-domain.com

Now push one last time, from your own machine in the directory you’ve cloned Gitlab into:

git push dokku deployment:master

Watch it go for a little while, and once the push has completed you should be able to log in with Gitlab’s default credentials at http://gitlab.your-domain.com. The default user is

root

and the default password is:

5iveL!fe

There you have it – a fully-working Gitlab install on your own server ready to act as your own code repository!

Did you find this useful? Drop me a comment below.