Heroku style application deployments with Docker

In this article, we describe how you can use Kontena's experimental features for deploying application with Kontena just like with Heroku!

Developing and deploying applications to Heroku was revolutionary when it was introduced. Developer could just focus on developing a killer app instead of configuring servers and build scripts.

Heroku, just like many other platform-as-a-service ("PaaS") solutions, allow developers to deploy application written in a supported programming language, to a hosted cloud platform. The deployment is typically made with git push to a PaaS platform specific repository. On deploy, the platform will detect the programming language and build & run the application.

With PaaS platforms, developers can enjoy highly automated deployment processes. Kontena is aiming to enable the same convenience for people moving away from PaaS solutions to Docker containers. Since Heroku is one of the most polished and developer friendly PaaS platforms out there, we wanted to see if it is possible to create similar development workflow with Kontena.

Getting an application running on Kontena

After you have provisioned Master node and host nodes you are ready to start deploying applications to Kontena. See Quick Start guide for more details

The first step of running your application on Kontena is to dockerize it. With Kontena it is easy, just call kontena app init command. It creates the necessary Dockerfile, docker-compose.yml and kontena.yml files.

The generated Dockerfile is by default based on Buildstep which enables Heroku-style application builds with Docker. Buildstep has a list of officially supported buildpacks that are built-in and ready to be used.

In addition to Dockerfile generation, Kontena parses the app.json manifest file and Procfile. Based on those files it describes necessary application and add-on services in kontena.yml and generates related environment variables in .env file.

When your application is dockerized you can deploy it with kontena app deploy command. On deploy Kontena builds Docker image for your application automatically and detects your application type based on the source code and prepares the required running environment for it.

After the built is ready Kontena pushes the created Docker image to image registry. By default Kontena uses a built-in self-hosted Docker registry, but you can change it in kontena.yml.

On deployment Kontena orchestrates Docker containers and deploys the app to host nodes.

When the deploy completes, you have your app and all necessary addon services up and running.

Example

Let’s try this out with simple Heroku styled Ruby/Sinatra application that has one endpoint that shows how many times page has been visited:

web.rb

require 'sinatra'  
require 'redis'

get '/' do  
  redis = Redis.new(:url => ENV['REDIS_URL'])
  redis.incr "count"
  "Hello, world called #{redis.get("count")} times"
end  

Then we define our application in app.json manifest with one openredis addon:

{
  "name": "Sinatra example application",
  "description": "This app is a basic Sinatra application.",
  "keywords": [
    "kontena",
    "ruby",
    "sinatra",
    "redis"
  ],
  "website": "http://www.kontena.io",
  "repository": "https://github.com/kontena/redis-example",
  "success_url": "/",
  "addons": [
    "openredis"
  ]
}

We also need to introduce our processes in Procfile

web: bundle exec ruby web.rb -p $PORT  

Now we are ready to dockerize our application by running:

$ kontena app init

It creates all the necessary Docker and Kontena related files and services and we can just deploy our app:

$ kontena app deploy

Scaling the application

In order to scale the application, we need to attach it to a Kontena Load Balancer. To do that, we must first create a load balancer service to the grid:

$ kontena service create --ports 80:80 internet_lb kontena/lb:latest

Then we can edit kontena.yml file and set number of running instances and attach service to the load balancer service. That can be done with external_links property and environment variables:

web:  
  ...
  instances: 2
  external_links:
    - internet_lb
  environment:
    - KONTENA_LB_MODE=http
    - KONTENA_LB_BALANCE=roundrobin
    - KONTENA_LB_INTERNAL_PORT=5000
    - KONTENA_LB_VIRTUAL_HOSTS=www.yourdomain.com,yourdomain.com

See example kontena.yml for the complete example.

After that we can just re-deploy our web service:

$ kontena app deploy web

Conclusion

We have demonstrated it is possible to have Heroku-like application development workflow when working with Docker containers. You can enjoy best parts of both worlds; super easy application development workflow combined with pure docker containers.

We are still working and experimenting with this feature so expect to see some changes in the future. Some of the improvements we are thinking about:

  • Automatically attach "web" services to Kontena's load balancer
  • Allow Heroku-like easy scaling for application
  • Make Buildstep produce smaller images. The current implementation produces images that are too big; typically over 1GB!

Let us know what you think and/or help us by contributing to Kontena open source project. Looking forward to see you again!

About Kontena

Kontena is a new open source Docker platform including orchestration, service discovery, overlay networking and all the tools required to run your containerized workloads. Kontena is built to maximize developer happiness. It works on any cloud, it's easy to setup and super simple to use. Give it a try! If you like it, please star it on Github and follow us on Twitter. We hope to see you again!

Image credits: Origami by Doug