Docker – Containers versus Virtual Machines

05 June 2015


There is a lot of talk in the industry at the moment about Docker (and containers in general). But, there also seems to be a lot of confusion about what Docker is, why you would use it, and how it is different than any other virtualization framework such as VirtualBox, VMWare, or Parallels. This confusion is especially prevalent in the developer community where systems administration work is often delegated to another team. Docker is a different kind of virtualization that solves common problems that software teams face everyday. Docker, and more generally a container, is something that every developer should learn about as they are likely going to need to use them in the coming years.

What problem does Docker solve?

In most organizations, a typical web application is developed on a developer's machine with a local database. Then, it is deployed to staging where the hardware is split into separate machines (virtual or physical). One for the web server and one for the database. Eventually, the application is deployed to production where the environment should perfectly match the staging environment, but usually does not for a variety of reasons.

In the scenario above, there is plenty that can go wrong when switching between environments. First, has the hardware been allocated? Has the configuration for each environment been properly setup to not point to the wrong database? Have the proper ports been exposed on the database servers?

As a consultant, I run into these problems often. Checklists are extremely helpful to get through the initial setup for a typical configuration. But, the process is still very iterative, time consuming, and difficult to estimate. There are too many variables, and usually too many responsible parties to talk to. Docker solves this issue by encapsulating your application into containers. These containers can simply be shipped from environment to environment whether it is another user's machine or the cloud. A developer can therefore build, run, and test software locally knowing that it will run identically no matter what environment it is in.

This ability to encapsulate and ship applications also solves other common developer issues. When a new employee joins a company or joins a team, it is not uncommon for them to spend up to a week setting up their machines. Containers can make this process easier by already encapsulating many of the required application dependencies.

Another common issue developers face involves environmental differences. If all of your environments are bundled in containers and are identical, you should never have to hear the common excuse, “It works on my machine” ever again.

How is Docker different then a virtual machine?

The basic confusion between Docker and virtual machines is that they are both forms of virtualization. But, virtualizing a machine has much different characteristics than virtualizing an application.

  • Guest Operating System - A primary difference between Docker containers and virtual machines is that while VMs have to house the guest OS, Docker runs as an isolated process on the host operating system and does not require a guest OS.
  • Size - Since Docker does not encapsulate a guest OS in the containers, containers are a lot smaller than virtual machines.
  • Speed - By running in-process and making the containers as lightweight as possible, Docker containers run much faster. This is especially true during startup.
  • Registry - Not only can you build your own Docker images from scratch like a virtual machine, but Docker also has a large repository of base images that you can use directly from your project.

Another difference between Docker and a virtual machine is that Docker inherently has provisioning built into its structure via dockerfile instructions. Provisioning is the process of getting a machine into a defined state. While this is possible with virtual machines, it requires additional tools such as Vagrant, Puppet, and/or Chef.

Limitation and workarounds

Because of the way Docker creates isolated processes on the host operating system, it currently only officially supports 64-bit Linux. This means that your host OS will need to be 64-bit Linux and your container will also need to encapsulate 64-bit Linux.

If your host OS is not 64-bit Linux, there are several options available. For example, Docker could be hosted inside of a virtual machine. For a lighter weight configuration, one could choose to use Boot2Docker.

Non-Linux 64-bit development

If your target OS is not 64-bit Linux, then Docker might not be the right platform for you. However, be careful to fully evaluate your situation before dismissing the idea entirely. For example, SQL Server and other Microsoft infrastructure aside, many IIS hosted websites (e.g. ASP.NET MVC) use very little of what is available in IIS. Therefore, why does your application need to be tied to IIS, the .NET framework, or even Microsoft? It is entirely possible to build a C# Nancy project, which is a very lightweight MVC-style web framework that uses many familiar things like razor syntax views. These projects could then be run on the Mono runtime and hosted on Docker. If your IT department is familiar with Apache, you can even use it to host the Nancy application. While this solution certainly is not for everyone, there is a growing number of possibilities beyond the vendors we typically align ourselves with.

If you, your organization, or your customers are not quite adventurous enough for such a non-proprietary technology stack but still want to use containers, do not fret. Microsoft is working on their own Hyper-V Containers.

Conclusions

Container technology is a powerful way to solve common DevOps problems. Although virtual machines will still have their place, containers are lighter, faster, and more easily extensible. Whether you use Linux, OS X, or Windows, you should expect containers to be a part of your development process in the next few years.