Heroku Style Application Deployments with Docker

Written by: Lauri Nevala
4 min read

This article was originally published on the Kontena blog by Lauri Nevala, and with their permission, we are sharing it here for Codeship readers.

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. A 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, allows developers to deploy applications 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 and run the application.

With PaaS platforms, developers can enjoy highly automated deployment processes. Kontena aims 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's possible to create a similar development workflow with Kontena.

Getting an Application Running on Kontena

After you have provisioned controller node and host nodes, you're ready to start deploying applications to Kontena. See our Quick Start guide for more details.

The first step of running your application on Kontena is to Dockerize it. With Kontena it's 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 a Docker image for your application automatically, detects your application type based on the source code, and prepares the required running environment for it.

After the build 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 add-on services up and running.

Example

Let’s try this out with a 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're 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 the kontena.yml file and set the 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 that it's possible to have a Heroku-like application development workflow when working with Docker containers. You can enjoy best parts of both worlds: a super-easy application development workflow combined with pure Docker containers.

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

  • 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 the 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 set up, 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!

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.