Simple tools are beatiful
This is a revised version of two earlier outdated posts of mine.
(Not only) the rails community is going all excited about playing around with docker containers instead of with full-blown virtual machines.
With dokku a (and there are many others) project aims to build a thin but super-soft layer between the containers (if you don’t know the difference yet: think of containers as if they were virtual machines for now) and your deployment-fu.
These tools scratch itches of mine: deployment for me is less fun than doing other stuff with a computer. But slim tools usually are quite fun. And heroku-style git-push-deployments can be really enjoyable.
- Set up a dokku guest that we can deploy a rails 4 app to.
- Run this dokku guest on a server in the wild.
- Let this dokku guest serve our app to the outside world.
- Have it make use of letsencrypt.
- Have a basic idea of how to backup your db and/or uploads.
- Ubuntu 14.04 system
- A bit of patience
- DNS set up to resolve your domain
Step one: create the VM
Instead of spoiling my main system with other package installations, configurations and tasks, I will create a virtual machine running ubuntu to be my docker/dokku host. I will call that machine
vlaada and it will be a minimal Ubuntu 14.04 (trusty) system. To be on the safe side, I will not create the VM by hand and will not use any heavy machinery like puppet or chef, but use
apt-get install python-vm-builder). Note that while I use kvm and libvirt here you can use other hypervisors.
To ease creation of the VM, I put the somewhat long commands in (ba)sh scripts:
Some options require special attention:
addpkg linux-image-generic: vmbuilder (?) bug workaround (you might not need it)
addpkg acpid: allows us to shut the machine down cleanly without logging in
addpkg apparmor: another workaround, otherwise docker/dokku won’t play nice with us (again, ymmv)
addpkg postgresql-client: will need this later to make postgresql database dumps, the dokku postgresql plugin won’t install this package for us
ssh-user-key: locks the machine down (a bit), use the public key with which you want to log into the system later
--execscript ...: assemble path to the
post_setupscript (see below); it is executed at the end of the build process
The content of
If that last part looks scary to you, it is. It basically allows the dokku and dokkulord users to sudo without password.
setup_dokku_vm vlaada will create and register a virtual machine.
On my favorite machine, this vm-creation-process takes around 20 minutes.
If you are impatient and want to see some white letters run over your black screen, the command above will tell you where to
sudo tail -f to to see what is happening (
.... logging to file: /tmp/tmpXXXXYYYZZZ). On inspection you will see that no magic happens.
If you use
virt-manager you can now easily connect to the VM host and see that
vlaada has been created and registered. It’s ready to start!
Now might be a good time to clone this machine, e.g. using
virt-clone --auto-clone -o vlaada --prompt (
apt-get install virtinst to get
virt-clone, this only applies to the libvirt setting I use).
This already happened in the
Login via ssh
As your key is already registered you can now login to the machine via ssh (you can also connect with
virt-manager if you want - even remotely!).
Make your ssh-keys known or passed around where necessary.
To find the IP of your virtual machine (if its dhcped like in my setup) you can look at the current dhcp-leases with
Assuming the IP is
ssh firstname.lastname@example.org into the machine to administrative tasks and
ssh email@example.com to run dokku commands.
Everything works? Great, lets make this fun possible at home!
Step 2: Configuring access to the dokku VM
vlaada (the dokku VM) lives on a server in the wild and it shall not be accessible from outside (except for ports 80 and 443). To access it, I will dig an ssh tunnel through the server.
~/.ssh/config I put
ssh vlaada-tunnel makes connections to the localhosts port 7722 end up at port 22 on the VM that we have set up (here, referenced by its IP
I also add an host entry
Now after digging the tunnel (
ssh vlaada-tunnel) I am able to
ssh vlaada into the dokku machine, which is somewhere out there, hidden in the wild. Cool.
Given that I authorized my key to perform dokku stuff
ssh dokku-vlaada will run dokku commands on vlaada.
You can configure dokku by digging a tunnel to port 80 (
ssh -L 8099:192.168.122.177:80 myhost) and visiting it (
http://localhost:8099 in that example) with a webbrowser. This will especially set the
/home/dokku/VHOST file content if using vhosts (which I do).
Create an alias
Now you can create an [alias (with nalias)][alias] to run dokku commands:
alias dokku-vlaada='ssh dokku@vlaada'
Alternatively in following examples you can run dokku as dokkulord from 192.168.122.177 yourself (
sudo dokku <command>) or “spell it out”
ssh dokku@vlaada <command>. For the latter (and the alias) the tunnel has to be dug first.
Configure http(s) forwarding/NAT
To expose port 80 and port 443 of your virtual machine to the internets you want to NAt these ports (e.g. using
Lets deploy a toy app
Afterward just a few minutes,
ruby-sample.myhost should be available (watch STDOUT). Brilliant!
Install postgres plugin
SQLite databases won’t work out of the box, so pick an app which uses postgresql in production configuration and install the postgres plugin (you only have to do this once):
dokku-vlaada plugin:install https://github.com/dokku/dokku-postgres.git
Create a postgresql database
db.<appname> as a name for the database.
dokku-vlaada postgres:create db.myapp
Create the app
dokku-vlaada apps:create myapp
And link it
dokku-vlaada postgres:link db.myapp myapp
Now add the remote to your rails app, e.g.
git remote add dokku dokku@vlaada:myapp .
And push it
git push dokku master
Setup DB, run the migrations
dokku-vlaada run myapp rake db:setup
Backup your database
dokku-vlaada postgres:export db.myapp > myapp.db.pgdump
Add some storage
If your app handles file uploads or any other data that should be persisted you will be happy to use the
Let us encrypt
With letsencrypt we have serious automated ssl certificates at hand for free and dokku has a plugin (in beta stage) for you.
Enter the awesomeness by installing the plugin
dokku-vlaada plugin:install https://github.com/dokku/dokku-letsencrypt.git
That was simple.
Installing a certificate is much more complicated:
That was tough, but now you have deployed a valid, trusted certificate and configured your nginx to use it. Please read the letsencrypt plugins README, as it also has some legal stuff on it.
vmbuilder step you might find following options helpful:
--mirror http://your-apt-mirror-cache-or-proxyThis might save you some time and network traffic.
- You can checkout the scripts at http://github.com/fwolfst/scripts/setup_dokku_vm .
- To have the app logging to stdout and seeing the logs via
dokku logs myappthe easiest way is to include the
rails_12factorgem in your Gemfile.
Having a better idea?
Awesome! Get in contact with me!