In this post we examine the key concepts related to Containers. We shall examine – basic container concepts, containers vs virtual machines, and then compare two key container technologies, viz. Docker & Heroku.
You shall also learn how to package your application in a Docker container and deploy it in production in Heroku.
Here are some basic concepts as we get started:
What is Heroku?
Heroku is a PaaS (Platform as a Service) cloud offering from Salesforce. Think of Heroku as a service, which simplifies the process of getting your finished app to your potential users – in just a few clicks.
You create your applications in a language of your choice and then upload it to Heroku. Heroku automatically spins up a container for your application with all the required runtime software (application server etc.).
What Are Containers?
Container is a self-contained wrapper for your application, which has everything you need to run it: code, runtime, system, and tools.
Containers are scalable, lightweight, and portable. As such they have become very popular today.
How Are Containers Different From Virtual Machines?
The following illustrations shows two servers one with virtual machines, the other with containers.
Virtual Machines
A virtual machine is essentially an emulation of a real computer which executes programs like a real computer. Virtual Machines run on top of physical machine using a piece of software called a hypervisor. These hypervisors can themselves run on either a host machine with it’s host OS or directly on top of “bare metal hardware”.
Multiple virtual machines running on one server will each have their own instance of an operating system. As an example, I run VirtualBox on my server. Inside this VirtualBox I have two different virtual machines each having a different OS (Windows & Linux).
Examples of virtual machines: Virtual Box, VMWare, Xen
Containers
Think of a containers as lightweight versions of a Virtual Machine.
Containers however share the host OS, so unlike a virtual machine, they do not require an OS to boot up when they are created. Thus containers are much faster and less resource intensive than virtual machines.
Examples of containers: Heroku Dyno, Docker
What Is Container Technology Under The Hoods?
A container technology like Docker utilizes the resources isolation features of the OS. As an example, earlier versions of Docker utilized LXC (Linux Containers) as an execution environment. However the new versions of Docker have their own execution driver called Libcontainer.
Similarly, Heroku uses the resource isolation features of Linux to allow independent “containers” to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.
Comparing Docker & Heroku
Both Docker and Heroku allow you to package your applications in modular self-contained units.
Self contained, independently deployable units of application which communicate with each other and with external systems through standard APIs are the foundation of a Microservices based design.
Customers generally like Docker because of portability and openness.
Customers generally prefer Heroku for scalability, security and fast development.
Demystifying Nomenclature in Docker & Heroku
The following illustration shows the nomenclature used in Docker and Heroku.
Docker:
• Dockerfile is a set of commands which defines how the final image should look like.
• Image is a self contained unit which has all the data, files, dependencies and settings you need to run your application.
• A container is a running instance of your image. When you start an image (i.e. an instance of your application), Docker spins up a container for you.
• The official Docker Index allows you to share your Docker images with the community.
After you create your application and package it as a Docker image you will need to deploy it on one of the supported infrastructures like AWS & Google.
Heroku too has a beta program for supporting Docker.
Heroku:
• Buildpacks are a set of scripts, which define how the image should be set up, & the runtime required.
• When you run your application on Heroku, Heroku creates a slug which is a compressed copy of your application. Similar to a Docker image, the slug contains all the dependencies packaged together.
• Similar to a Docker container, a dyno on Heroku is a lightweight container which runs your slug (compressed application with all the dependencies).
• Elements Marketplace in Heroku allows you to get pre-configured components for your application.
In the case of Heroku, after you create your program you will copy it to an “application” you have created in Heroku. This application in Heroku is initially an empty scaffolding, and when you copy your code to it, Heroku will create a slug (compressed version of your code) and associate it with a Dyno for runtime.
Why Run Docker on Heroku?
Docker is a software which allows your application (& all dependencies etc.) to be packaged in a self-contained envelope (i.e. container). You can then take this container and deploy on any server or cloud platform (e.g. AWS, Heroku) which supports Docker containers.
Heroku provides the ability to package your application in a self-contained container. In addition, Heroku also gives you the ability to deploy and run the container.
In addition to the native container capability in Heroku (ie. Dynos); now you can also run your Docker containers on Heroku.
Following are the key considerations in running a container in production environment:
- High Availability
- Security & Patching
- Scalability & Auto-Load Balance
- Database Administration
- Auto-fail over and database backups
- Log Management & Monitoring
- Image Management
- Deployment Process & Tools
- Support
Heroku is a PaaS (Platform as a Service) which provides the services mentioned above which are critical for production environments.
Heroku now has introduced beta support for Docker. You can package your applications in Docker Container and deploy it on Heroku.
How is this different from the previous Docker support in Heroku? The previous Heroku support for Docker was for local development only. The new beta support for Docker in Heroku allows you to deploy your Docker images on Heroku live environment.
Deploy Your Docker Container on Heroku: A Step by Step Guide
Step – 1. Set up Docker on your local environment
• Install Docker for Mac: https://docs.docker.com/engine/installation/mac/
• Older Docker tools like Kitematic, Docker Toolbox and Boot2Docker are now replaced with the new beta Docker for Mac and Docker for Windows software. Those earlier tools (e.g. Docker Toolbox) end up installing a virtual machine on your computer which may cause issues. Avoid using them.
• After installing Docker for Mac, experiment with the steps listed in “Getting Started with Docker”: https://docs.docker.com/docker-for-mac/
• Docker has a known issue of sucking up a lot of your memory. A Docker restart usually fixes this.
Step – 2. Set up Heroku on your local environment using Heroku Trailhead: https://developer.salesforce.com/trailhead/en/heroku_enterprise_baiscs/your_first_deployment
Step – 3. Deploy Docker on Heroku using the Heroku Docker “Container Registry and Runtime” documentation: https://devcenter.heroku.com/articles/container-registry-and-runtime
This documentation guides you in:
– Creating an app (essentially an empty scaffolding) on Heroku
– downloading a small pre-built Hello World program written in python. This package contains a Dockerfile also.
– Packaging it in docker and pushing it to Heroku
What Happens When You Push Docker Image to Heroku?
When you push Docker images to the Heroku container registry for an app, those images are immediately released to the Heroku app. Docker images are the functional equivalent of slugs built with buildpacks. Docker images run in dynos the same way that slugs do, and under the same constraints.
Now you have your application running on Docker inside Heroku!
Resources
Link to the older support for Docker in Heroku only for local development: https://blog.heroku.com/introducing_heroku_docker_release_build_deploy_heroku_apps_with_docker (I have mentioned this here for completeness only. Please do not use this guide anymore).
Link to the new & updated support for Docker in Heroku: https://devcenter.heroku.com/articles/container-registry-and-runtime