Multipass vs Vagrant for Creating Docker-ready VMs

Dec 5, 2024 by Zacharia Mansouri | 399 views

Virtualization Docker

https://cylab.be/blog/368/multipass-vs-vagrant-for-creating-docker-ready-vms

When it comes to managing Virtual Machines that run Docker images, developers often face a choice between various tools for VM creation. Two popular options, Vagrant and Multipass, offer distinct approaches, each with its own strengths and limitations. Multipass, designed by Canonical, is focused on simplicity and lightweight VM management, making it a strong choice for quick deployments. On the other hand, Vagrant, widely used for development environments, is highly customizable and integrates well with various provisioning tools.

s.png

In this blog post, we’ll compare how to automate the deployment of Docker containers inside VMs using both these technologies, which can be useful for situations such as when you need:

  • pre-configured environments for training or demonstrations
  • air-gapped deployments in critical infrastructures
  • generation of back-ups to recover from some disaster
  • creation of a lightweight CI/CD infrastructure

We’ll dive into a side-by-side comparison of Multipass and Vagrant, analyzing their capabilities for creating VMs that run Docker images. Whether you’re looking for flexibility or speed, this guide will help you decide which tool best suits your workflow.

Installation

Multipass

Multipass is a tool to get an instant Ubuntu VM with a single command since it can launch and run virtual machines and configure them with cloud-init. As stated on the Canonical official website, its installation can be achieved as follows:

sudo snap install multipass

Vagrant

Vagrant is described as a command line utility for managing the lifecycle of VMs by isolating dependencies and their configuration within a single disposable and consistent environment.The installation of Vagrant requires more steps. The Hashicorp documentation has a page dedicated to its installation.

Docker VM Configuration & Deployment

The Docker container to deploy is a basic nginx server. We’ll see how to deploy it in a VM using Multipass and Vagrant.

Multipass

Folder structure and files

The following structure includes a launch.sh script, used to initiate the overall setup process. Inside the 2transfer/ directory, there is an install.sh script, which contains the VM configuration and creation commands, and a project/ directory that uses the docker-compose.yml file within it to deploy the nginx server. In short, launch.sh orchestrates the transfer of files and execution of install.sh inside the VM, which then handles the setup and deployment of the Docker project.

|____launch.sh
|____2transfer/
	 |____install.sh
	 |____project/
		  |____docker-compose.yml

The launch.sh script automates the creation and setup of a Multipass VM named my-vm. It first launches the VM with 2 CPUs, 2 GB of memory, and a 10 GB disk. Then, it transfers all files and directories from the 2transfer/ folder to the VM. Afterward, it executes the install.sh script inside the VM to handle the deployment of the nginx server.

launch.sh

#!/bin/bash

multipass launch -n my-vm --cpus 2 --memory 2G --disk 10G
multipass transfer -r 2transfer/* my-vm:.
multipass exec my-vm install.sh

The install.sh script configures a system to use Docker and Docker Compose. It updates the package list and installs Docker, enabling and starting its service. It adds the current user to the docker group for permission to run Docker commands. Next, it installs Docker Compose, verifies both installations, and navigates to the project directory to build and deploy the Docker Compose project in detached mode.

2transfer/install.sh

#!/bin/bash 

# Update package list
sudo apt update

# Install Docker
sudo apt install -y docker.io

# Enable and start Docker service
sudo systemctl enable docker
sudo systemctl start docker

# Add the current user to the docker group
sudo usermod -aG docker $USER

# Install Docker Compose
sudo apt install -y docker-compose

# Check Docker and Docker Compose versions
sudo docker --version
sudo docker-compose --version

# Navigate to the project directory and start the Docker Compose project
cd project && sudo docker-compose up --build -d

As previously stated, the Docker project is a simple nginx server.

2transfer/project/docker-compose.yml

version: '3'
services:
  web:
  image: nginx:latest
  ports:
    - "8080:80"

Deployment

Executing ./launch.sh will automate the creation of a Multipass virtual machine, transfer necessary files to it, execute the setup script (install.sh) to configure the VM and deploy the Docker Compose project.

./launch.sh

Vagrant

Folder structure and files

|____Vagrantfile
|____project/
	 |____docker-compose.yml

This structure contains a Vagrantfile for configuring and provisioning a VirtualBox VM using Vagrant, and a project/ directory containing a docker-compose.yml file. The Vagrantfile sets up the VM and provisions it to use the docker-compose.yml file within the project/ directory to deploy the nginx server.

The Vagrantfile sets up a VirtualBox VM named my-vm with 2 GB of RAM, 2 CPUs, and Ubuntu 20.04 as the base OS. It disables the default synced folder, shares the project directory, and forwards port 8081. The VM is provisioned using a shell script that updates the system, installs Docker and Docker Compose, enables Docker, and deploys a Docker Compose project from the shared folder. This configuration automates the setup of a development environment for Docker-based projects.

Vagrantfile

Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/focal64"
    
    config.vm.provider "virtualbox" do |vb|
        vb.memory = "2048"
        vb.cpus = "2"
        vb.name = "my-vm"
    end

    config.vm.synced_folder ".", "/vagrant", disabled: true
	config.vm.synced_folder "project", "/vagrant/project"
	config.vm.network "forwarded_port", guest: "8081", host: "8081"
	config.vm.provision "shell", keep_color: true, inline: <<-SHELL
		mkdir /home/vagrant/project

		cp -r /vagrant/project/* /home/vagrant/project

		# Update
		sudo apt-get update

		# Install dependencies
		sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

		# Add Docker GPG key and Docker repo
		curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
		sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"


		# Install Docker
		sudo apt-get install -y docker-ce

		# Add vagrant user to docker group
		sudo usermod -aG docker vagrant

		# Install Docker Compose
		sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
		sudo chmod +x /usr/local/bin/docker-compose

		# Verify Docker Compose installation
		docker-compose --version

		# Start Docker
		sudo systemctl enable docker
		sudo systemctl start docker

		# Deploy and run docker containers
		cd /home/vagrant/project
		docker-compose up --build -d
	SHELL
end

Once again, as previously stated, the Docker project is a simple nginx server.

project/docker-compose.yml

version: '3'
services:
  web:
  image: nginx:latest
  ports:
    - "8080:80"

Deployment

With a single command, Vagrant will create and configure the VM as specified in the Vagrantfile, automatically provisioning it to deploy the nginx server:

vagrant up

Encountered Errors

vagrant up Error: No Usable Default Provider Found

The error occurs because installing Multipass enables KVM, which conflicts with VirtualBox. This issue was resolved by ensuring VirtualBox’s kernel modules were correctly installed and configured. Follow these steps to fix it:

  1. Verify VirtualBox installation:

    VBoxManage --version
    

    If it returns an error, proceed with the following steps.

  2. Update the system:

    sudo apt update
    sudo apt upgrade
    
  3. Install required kernel headers and modules:

    sudo apt install linux-headers-generic
    sudo apt install linux-headers-$(uname -r)
    sudo apt install virtualbox-dkms
    
  4. Reconfigure VirtualBox kernel modules:

    sudo dpkg-reconfigure virtualbox-dkms
    sudo modprobe vboxdrv
    
  5. Restart and check VirtualBox service:

    sudo systemctl restart virtualbox.service
    sudo systemctl status virtualbox.service
    
  6. Verify VirtualBox is working:

    VBoxManage --version
    

This should now return the version successfully.

Switching Between Multipass and VirtualBox (Vagrant)

If you use VirtualBox as a provider for Vagrant instead of KVM, you need to adjust kernel modules due to conflicts between KVM and VirtualBox, since Multipass uses KVM (libvirt).

To switch from VirtualBox to Multipass, stop all VirtualBox VMs, then enable KVM:

sudo modprobe kvm
sudo modprobe kvm_intel

To switch from Multipass to VirtualBox: stop all Multipass VMs, then remove KVM modules:

sudo rmmod kvm_intel
sudo rmmod kvm

Multipass VS Vagrant Comparison

When choosing between Multipass and Vagrant, your decision largely depends on your project’s complexity and your need for customization.

Ease of Use

Multipass stands out for its simplicity and lightweight nature. Designed to quickly run Ubuntu VMs, it requires minimal configuration, making it ideal for straightforward tasks like installing software such as Docker. Its commands are intuitive, and it integrates seamlessly with Ubuntu, since it’s a product of Canonical. This makes Multipass perfect for developers seeking a fast way to set up a VM.

On the other hand, Vagrant offers much greater flexibility and power, particularly for more complex setups. With a robust ecosystem of OS images (called “boxes”) and support for multi-VM configurations, it’s built for replicating environments consistently. Whether you’re provisioning with tools like Ansible or working across various providers like VirtualBox and Docker, Vagrant gives you fine-grained control. While its initial setup can be more complex, its extensive capabilities make it worth the effort for more demanding projects.

Performance

Multipass is optimized for Ubuntu and uses the native hypervisor on your host system (such as KVM on Linux), eliminating the need for additional hypervisors like VirtualBox. This makes it efficient and lightweight, particularly if you’re deploying to Ubuntu servers in production.

Vagrant, depending on the provider you use, can be heavier. For instance, VirtualBox-based configurations can consume more resources. However, Vagrant’s Docker provider allows you to bypass full VMs entirely by running containers, potentially delivering better performance for containerized workflows.

Provisioning and Configuration

Multipass takes a minimalist approach, offering limited provisioning options. You can configure instances via bash scripts or by SSHing into them, but it’s less suited for complex automation or for environments beyond Ubuntu.

In contrast, Vagrant supports detailed provisioning scripts directly in the Vagrantfile, whether you’re using shell scripts or advanced tools like Ansible. Vagrant is also compatible with a wider variety of operating systems and hypervisors, making it a powerful choice for automating multi-OS or multi-VM setups.

Docker Integration

Multipass doesn’t have built-in Docker integration, though Docker can be manually installed on the VM. This works well for basic use cases, like running Docker Compose, but lacks the deeper integration or automation that some workflows may require.

Even though we do not show it in this blog post, Vagrant, however, provides native Docker support. You can use Vagrant to manage Docker containers without needing a full VM. Its Docker Compose provider is particularly useful for orchestrating containers alongside other VMs, making it an excellent option for hybrid setups.

Flexibility and Extensibility

If simplicity is your priority, Multipass is a great choice. It’s tailored for Ubuntu environments and quick-start scenarios but lacks the customization options of Vagrant.

Vagrant, on the other hand, is extremely versatile. Whether you’re managing multiple VMs, integrating complex provisioning tools, or combining VM and container workflows, Vagrant gives you the control you need to handle sophisticated infrastructure setups.

Conclusion

Multipass is ideal for lightweight, Ubuntu-focused tasks. If you need a quick and efficient way to spin up a single VM for Docker or other simple software installations, Multipass provides a smooth and streamlined experience. Vagrant is the tool for more demanding projects requiring flexibility and automation. Whether you’re managing diverse OS environments, writing detailed provisioning scripts, or coordinating multi-VM setups, Vagrant shines in its ability to replicate complex environments across teams and machines. Choosing between Multipass and Vagrant therefore depends on the level of precision and the scale of the project you’re working on.

This blog post is licensed under CC BY-SA 4.0

This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept