Build a little PAAS with Dokku

Most of the sites I create are usually a good fit for Gitlab pages, but I usually need to setup small web applications, micro-services and other tiny pieces that automate processes, act as glue between systems or support static sites.

Until now I used a combination of self-hosted apps, relying on Heroku and now.sh free plans for experiments, but I'm getting more and more used to the CI workflow, and it's a always a good idea to consolidate services in containers.

Enter Dokku

Web apps are today made of many components: the old-school ones like a web-server, an application server, a database plus more modern elements such as messaging, caches, queues, workers etc.

There are alternatives for deploying web apps:

  • system setup: this means setting up all individual services on a (blank) dedicated VPS running Linux. Not really difficult but a little hard to keep up with all the configuration files you need to edit for adding a new app (unless you run a single app per VPS)
  • system setup (automated): frameworks such as chef allow to automate the setup of the system through SSH commands, you write a recipe to deploy your app and execute it in a single command
  • CI (deployment only): using a combination of recipes and containers, CI services can orchestrate deployment but not serving the application
  • PAAS (heroku, openshift,): companies offering managed deployment of the app, they require to define the structure and build process through config files and plugins. Most come with cli commands to manage the deployment and use GIT to transfer and deploy project source code.
  • containers (Docker): apps are run in isolated containers (similar to chroot) that can be built according to recipes, it's possible to link containers (Services) and to provide data volumes, private
    networking etc. Containers are portable and transparent to the hosting platform and dependencies.

Containers, especially Docker works very well. The level of portability and replicability of the development and production environment are really helpful. Docker on its own is powerful but needs some orchestration and automatic deployment system to be really effective.

I mainly use some sort of CI plus docker-compose, for example on fablabs.io. This approach is very powerful but a little slow, since deployment is done through external machines.

Every time I want to setup a new application I need to prepare a docker-compose file, but also to setup a server project, ssh keys, some proxy web server that exposes my app, SSL certificates, logs, and so on.

It's isn't really hard to do, but little repetitive and time consuming (and prone to human error). I could automate most of this using a tool like Chef, but each project is a little different and time is also a constraint.

Dokku provides a nice alternative to this approach, if you prefer an Heroku-like experience instead of a more advanced CI deployment setup, or simply don't have a sysadmin at hand.

This is the main goal of Dokku and I can say that they managed to create a workable alternative to the popular commercial PAAS.

The only noticeable different. You don't have a local cli, but work through SSH with the dokku command. I quickly added a shell alias that maps dokku to ssh -t dokku@my.dokku.server dokku and that's it.

There are also a number of command line clients to get a more Heroku-like experience.

Plugins in Dokku provide access to databases like Heroku does. Just remember this is a self-hosted service, so you are responsible for backups and off-site storage. Each plugins provides its way of backing up the data.

You can also add persistent volumes on the filesystem, that are mounted into the apps, all managed via the dokku command. In this case you can use snapshots from the VPS provider as an effective backup means.

For services that are not provided you can still run an instance of anything in a docker-container, or simply rely to a third party provider.

I appreciate the minimalistic philosophy of the project. Few things but well done.

Installing

Installing Dokku is very easy if you do it on a Linux VPS. For this purpose I upgraded and cleaned up a Digital Ocean VPS with 1GB of RAM. [Check the install instructions].

After installing make sure you add all the plugins for postgres, redis, mongodb and most importantly Let's encrypt.

Setting up a wildcard domain is a good idea, this way you will be able to host the apps on subdomains.

What's cool

Having your personal Heroku feels powerful. Many projects will fit on a VPS with git-based deploy as a bonus.

Dokku abstracts aways some boring docker details and the installation is super easy.

The software feels polished and stable. Lots of plugins and a good project history for the last few years.

What I don't like

Portability, mainly.

Docker-compose trained me to pretend I can just pull and push to a server and have all services rebuilt for me. Also the development environment matches 1:1 the production environment. No surprises when deploying.

To port a service to Dokku starting from a docker-compose project, I need to de-couple any database, queue or external service and run those as plugins. I can still use docker for any build or deploy process but I'm limited to a single docker file per app.

I need to investigate this further, but I still see no other alternative than to install dokku on my local machine and replicate the same setup on the deployment server, or use locally a docker-compose file that is somehow matched to the configuration on the Dokku server.

It is also true that this depends on how complex the app is and if it relies on external db services.
For apps that mainly do integration, only relying on config files for example, then this limitation is not a big issue.

No horizontal Scalability

It's easy to scale up a VPS, but Dokku won't scale horizontally. So you will always be bound to the power / storage your VPS can handle.

And while adding more power is easy, also costs will grow quickly.

Conclusion

I think Dokku does much more for you than docker-compose. It gives you a quick intuitive way to deploy simple apps, trying to automate the process as much as possible. With the addition of domain virtual hosting and let's encrypt automation, I would say it is a perfect solution for low-volume apps and prototypes that need a database, API, microservices and so on.