Moving to Containers Part 1: Building a PaaS

I’ve done my research and I’m mostly ready to build my dream PaaS, most of the pieces are assembled. So far we have

  • Dokku as the PaaS layer
  • NodeJS build pack for app(s)
  • TokuMX for persistence (experiemental)
  • Redis
  • Graylog2 (for system and app logging, experiemental)
  • Elasticsearch (for graylog2 mostly)

I’ll begin by talking about setting up Dokku. First you’ll need a host for dokku, (preferably a clean Ubuntu 13.04 x64 VM) and a domain to get started. As we run most of our infrastructure on DigitalOcean I’ll start by spinning up a VM Instance there.

Once setup, installing dokku is extremely easy, just copy and paste the bootstrap script.

I oped for the the development version but otherwise you can install the stable 0.2.1 version.

If deploying a node-js application don’t forget to create a procfile.

Once done, add you ssh keys to dokku, add dokku as a remote and push away!

You should get something like

edude03$ git push dokku master
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 1.62 KiB | 0 bytes/s, done.
Total 7 (delta 1), reused 0 (delta 0)
-----> Cleaning up ...
-----> Building dokkutest ...
remote: warning: You appear to have cloned an empty repository.
remote: HEAD is now at 559ba0f... forget dependancy
       Node.js app detected
-----> Resolving engine versions

       WARNING: No version of Node.js specified in package.json, see:
       https://devcenter.heroku.com/articles/nodejs-support#versions

       Using Node.js version: 0.10.21
       Using npm version: 1.3.11
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
<-- Installing dependencies --> 
-----> Building runtime environment
-----> Discovering process types
       Procfile declares types -> web
-----> Releasing node-test-app ...
-----> node-test-app linked to redis/node-test-app container
-----> Deploying node-test-app ...
=====> Application deployed:
       http://node-test-app.dokkutest.melenion.com

And we’re good! Alright and does are app throw an error as expected?

edude03$ http dokkutest.dokkutest.melenion.com/error
HTTP/1.1 500 Internal Server Error
Connection: keep-alive
Content-Length: 17
Content-Type: text/html; charset=utf-8
Date: Thu, 30 Jan 2014 04:57:34 GMT
ETag: "-350989751"
Server: nginx/1.4.4
X-Powered-By: Express

An error happened

Yep everything looks good!

There was a few other plugins I ended up needing to make things run smoothly, namely dokku-rebuild and user-env-compile

The former allows me to rebuild a container without a git push, which is really helpful for fixing intermitted issues (memory leaks for example) and testing certain features.

The latter allows me to set environment variables really easily by listing them in a .env file. This feature is really useful when you’re deploying an app to a new server and you don’t want to dokku config:set a bunch of variables by hand.

Well that’s part 1 of building a PaaS, in the next section we’ll look at configuring Redis and MongoDB.