Image alt

Docker and Vagrant are two very popular tools in the development community, and as such – they face a lot of criticism and praise at the same time. But, is there a practical difference between using one over the other? Let’s find out by digging deeper.

A common misconception is that Docker is the successor of Vagrant (a “newer or better version of Vagrant”) and that the two tools are competing. This may be true in some contexts where both tools are used purely to set up a quick local development environment. However, with a deeper look, we start to see significant differences when applying one or the other.

What is Docker?

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.

https://docs.docker.com/get-started/overview/

What is Vagrant?

Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent workflow to help maximize the productivity and flexibility of you and your team. To achieve its magic, Vagrant stands on the shoulders of giants. Machines are provisioned on top of VirtualBox, VMware, AWS, or any other provider. Then, industry-standard provisioning tools such as shell scripts, Chef, or Puppet, can automatically install and configure software on the virtual machine.

https://www.vagrantup.com/intro

Simply said, Docker is a platform for creating, shipping, and running containers, whereas Vagrant is a tool for defining and provisioning development environments as Virtual Machines.

The place where the two tools overlap most is the possibility to create and share environments in a repeatable and predictable way. All other features have completely different use cases.

Is Docker more lightweight than Vagrant?

Docker is much more lightweight than Vagrant and can handle a larger number of running containers than Vagrant can handle virtual machines – on top of the same Host machine.

The reason hides in the fact that Vagrant integrates with a couple of “full” virtualization software like VMWare or VirtualBox. When Vagrant uses them internally, those will create a virtual partition on top of the Host machine (e.g. a large single file to hold the full operating system). This partition will be used to boot a complete operating system ( Linux or Windows) with all of the dependencies the OS might need, embedded.

This process, naturally, is slower and heavier, because the idea is to make the Virtual Machine as much detached from the Host Operating System as possible, making the Virtual Machine – super portable.

On the other hand, Docker uses the resource isolation features of the Linux kernel (such as cgroups and kernel namespaces). Additionally, Docker doesn’t rely on third-party virtualization software like VMWare or VirtualBox. Instead, internally it relies on a couple of Open Source containerization technologies that take advantage of the mentioned native Linux kernel features.

If we have to oversimplify, a single running Docker container is just another running process within the underlying Linux-based operating system. A process, similar to your Browser or Music Player, but much more isolated (potential malicious code within a Container has limited access to the Host machine and can be constrained in terms of resources – CPU and RAM).

A Vagrant virtual machine, on the other hand, is a second Operating System, running inside the regular Host machine Operating System. Something like a Dual-Boot, but running simultaneously.

Running a process is far cheaper than running an OS. That’s why running a larger number of Docker containers is possible than Vagrant VMs on top of the same hardware.

The downside of Docker, compare to Vagrant in this context is – since Docker relies on Linux kernel features – the underlying Host OS needs to be a subset of Linux (Linux, Ubuntu, Debian, Windows WSL2, MacOS, etc). Vagrant has no such limitation, so long as the virtualization software of your choice (VMware or VirtualBox), supports that OS.

When to use Docker and not Vagrant?

Despite the similarities, there are use cases that make Docker a clear winner for professionals that have a need for tools like these two.

Deploying Multi-Cloud apps in a containerized manner is one of them. Docker makes it very easy to pick AWS, Microsoft Azure and Google Cloud as your cloud of choice at the same time, and deploy the same app to all 3 of them, using an orchestrator tool like Terraform, Chef or Kubernetes. Given that all cloud providers support Linux as an operating system, and Docker is very good at containerizing apps on top of Linux hardware – picking it is usually a no-brainer in such use cases.

Why not Vagrant? Because cloud servers usually already run Linux natively. There’s no need to run Linux Virtual Machines (provisioned by Vagrant) on top of Linux hardware, provided by the Cloud provider. This adds extra overhead and limits the possibility to scale and run a higher number of apps in parallel on top of the same cloud hardware (e.g. you can only run a few instances of your web app, replicated, on top of an AWS EC2 machine, whereas with Docker you can run a couple of dozen replicas, due to the lack of virtualization overhead; additionally Docker doesn’t require the third-party virtualization software like VirtualBox or VMware).

When to use Vagrant and not Docker?

If you have a cross-functional with different expertise levels (including junior developers who know very little about best practices and the proper configuration of their work environment).

If you run a remote software development team and want to enforce a consistent and well-working development environment with the possibility of “version control” (incremental updates) of that environment.

If you are working with a legacy app that requires complex configuration or OS-specific dependencies (e.g. special PHP extensions installed, FFMPEG, cURL, imagemagick, etc) but your team uses different underlying Operating Systems.

What is your experience working with Docker and Vagrant? Do you have a favorite?