“It works on my machine.” This line has become an excuse often overused by developers to escape the burden of having to investigate problems experienced by end users that they are unable to replicate on their development machines. While this may excuse developers—after all, they didn’t experience the problem during development and therefore couldn’t have anticipated it happening to some users—it doesn’t solve the problem.
Sometimes, issues are caused by end user mistakes, such as skipping a step in an installation process. Often, however, the problem arises from some disparity in the development and server or user environments. With the vast assortment of machine configurations in use—different operating systems, hardware specifications and software versions—even the slightest differences in development and production device configurations can cause dramatic differences in the behavior of many applications.
This can be a serious issue, as it requires members of the development and operations team to identify the root cause of the problem, which potentially introduces unexpected and often significant delays in deployment and production schedules. Especially in the DevOps culture where rapid development, frequent deployment and highly dependable releases are of highest priority, such unexpected delays are completely unwelcome.
Thankfully, there are a number of tools that have emerged to address this very problem. In this article, we take a close look at two popular tools with two different approaches to solving the problem of environment disparity: Vagrant and Docker. Like many DevOps tools and technologies such as continuous integration, these tools work well with all types of project setups, including IT outstaffing (dedicated development teams). Let’s compare these two solutions and see which types of scenarios each one is best fit for.
Vagrant vs. Docker
Vagrant offers to solve the aforementioned problem by enabling developers to easily create and manage virtual machines (VMs) in which they can develop, test and deploy applications. By using a VM, a developer or DevOps engineer is assured that as long as the application is run within the virtual machine, its behavior will be the same regardless of the actual hardware and operating system of the computer that the VM is running on.
Docker offers a similar solution, but uses a different technology. Instead of using virtual machines, it uses containers, which are similar to Linux Containers (LXC) that are included in Linux systems. Containers serve a similar purpose as virtual machines, but at a much less extensive level and, therefore, are much more lightweight. Rather than isolating an application in its own virtual computer with a full operating system, containers simply isolate an application inside an environment with the minimum components necessary to run the application. This includes system libraries and tools, settings and configuration files and a runtime environment. Compared to virtual machines, containers consume much less resources from the actual machine on which it is being hosted. Docker has a comprehensive documentation library that includes information on what Docker and Docker containers are, how to install Docker and how to execute a Docker run.
Vagrant and Docker share some common goals. For instance, in software development, both tools enable a more streamlined and consistent software development and deployment workflow by eliminating the need to worry about the application behaving differently in different machines. Moreover, it offers some degree of security to the host machine: Since the application is isolated from the rest of the system, issues caused by one application should remain within the scope of its environment and should not break the rest of the system.
There are, however, a number of important differences between Vagrant and Docker that make them suitable for different types of applications. Let’s examine more closely how these two differ.
Scope of Isolation
While both Vagrant and Docker wrap applications into isolated environments, they differ in the degree to which these applications are isolated—or, effectively, the scope of the isolated environments. For Vagrant, the scope is the entire operating system: An application can access any and all components of the full virtualized machine and operating system it is being run in. For Docker, on the other hand, the scope is much narrower, as an isolated environment is limited to a single application or service: Each container is created specifically for an application. Effectively, this implies that with Vagrant, a single isolated environment can run multiple applications at once, while with Docker, running multiple applications will typically require the use of a separate isolated environment for each one.
Since Vagrant virtualizes an entire machine with a full operating system, it naturally has a high overhead cost and consumes a lot of resources from the host machine. With Docker, on the other hand, an app within a container shares the same kernel—the core module or component of an operating system—with both apps in other containers and the host machine itself. This enables containers to have much less overhead and subsequently consume much less resources from the host machines than do virtual machines. In effect, a host machine running apps with containers can run up to three times as many applications as it can with virtual machines. Moreover, since launching apps within containers won’t necessitate having to wait for the virtual OS to boot up, launching apps can also be substantially faster with Docker than it is with Vagrant.
Vagrant and Docker also have their own limitations. Docker, for instance, is currently natively available to two operating systems: Linux, where it uses the Linux Kernel, and Windows, where it uses the Windows kernel. Docker is also available for MacOS, although it runs Docker containers on top of a Linux virtual machine. Moreover, Docker has some security issues—its use of containers make it less secure than Vagrant. Since applications within Docker containers share the same kernel with each other and with the host machine, it’s possible for a malicious program within a Docker container to affect other containers and even harm the host machine itself.
While Vagrant, which uses virtual environments, is much more secure in this regard, it is limited in that it is meant only as a tool for development and generally not recommended for use in production environments. In other words, it is meant to provide a convenient way to virtualize the environment of the server to which an application is eventually going to be deployed, but once in production, the application must be run directly on the host machine. On the other hand, Docker provides a consistent environment for applications throughout the entire software development workflow, from creation to production.
Being able to isolate applications into their own controlled environments has proven to be extremely useful for software development, as it eliminates many hardware and software incompatibility problems that applications may run into when executed in different machines. This is particularly useful in DevOps environments, as it streamlines the whole software development workflow by eliminating sources of unexpected problems, thereby potentially shortening development cycles.
We have looked into two popular tools for environment isolation, Vagrant and Docker. Both isolate applications from the host machine, although to varying degrees and using different technologies. Vagrant uses virtual machines, which can support multiple applications at once, but can be heavy on resource consumption and is only recommended for use during development. Docker, on the other hand, uses containers, which support only single applications, but is much lighter in terms of resource consumption and can be used both during development and during production.
As such, these two tools cater to different business needs. If you require the development of a complex system of multiple applications interacting with each other, using Vagrant may be beneficial, but if you’re aiming to create a single portable application and want to minimize resource consumption, then Docker is the way to go.