Skip to content

This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!


Vagrant

Vagrant is a tool for managing and configuring virtualized development environments.

Reference(s)

Table of contents


Avoid dotfile madness

Prior to installation, make sure you stay in control of your home directory.

Prerequisite(s)

See how to handle Vagrant related dotfiles.


Install

TODO

$ wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update && sudo apt install vagrant
$ sudo dnf install -y dnf-plugins-core
$ sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
$ sudo dnf -y install vagrant
# emerge -a app-emulation/vagrant
# nix-env -iA nixos.vagrant
# nix-env -iA nixpkgs.vagrant
# pacman -S vagrant
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install vagrant
# xbps-install -S vagrant
# zypper install vagrant

Config

Tips

  • From time to time, one can delete the content of $VAGRANT_HOME/.vagrant.d/tmp/ to save disk space.

Vagrant with KVM QEMU

See https://docs.cumulusnetworks.com/cumulus-vx/Development-Environments/Vagrant-and-Libvirt-with-KVM-or-QEMU/


Use

  • Resize a VirtualBox VM (https://gist.github.com/christopher-hopper/9755310):

    $ VBoxManage clonehd "ubuntu-xenial-16.04-cloudimg.vmdk" "clone-disk1.vdi" --format vdi #
    $ VBoxManage modifyhd "clone-disk1.vdi" --resize 102400                                 # (size in MB)
    $ VBoxManage clonehd "clone-disk1.vdi" "clone-disk1.vmdk" --format vmdk                 #
    $ mv clone-disk1.vmdk ubuntu-xenial-16.04-cloudimg.vmdk                                 # resize vmdk to 50Go
    
    $ rm clone-disk1.vdi # cleanup
    

  • Initializes the current directory to be a Vagrant environment by creating an initial Vagrantfile if one does not already exist:

    $ vagrant init generic/gentoo # example with a gentoo box
    

  • Create and configure guest machine according to your Vagrantfile:

    $ vagrant up
    

After a vagrant up, the guest machine /vagrant folder is synced with your local project (on the host machine, where you ran the vagrant up command, where your .vagrant and Vagrantfile files should be located)


  • Print the state of all active Vagrant environments on the system for the currently logged in user:

    $ vagrant global-status
    

  • Print the state of a machine Vagrant is managing:

    $ vagrant status vm-name-or-vm-id
    

  • Shut down the running machine Vagrant is managing:

    $ vagrant halt vm-name-or-vm-id
    

  • Stop the running machine Vagrant is managing and destroys all resources that were created during the machine creation process. After running this command, your computer should be left at a clean state, as if you never created the guest machine in the first place:

    $ vagrant destroy
    

  • Copy a file from host to vagrant guest (via default vagrant port 2222, check it with $ vagrant port):

    $ scp -P 2222 /home/user/test.file vagrant@127.0.0.1:/home/vagrant/downloads
    

  • Copy a folder recursively from host to vagrant guest (via default vagrant port 2222, check it with $ vagrant port):

    $ scp -P 2222 -r /home/user/testfolder vagrant@127.0.0.1:/home/vagrant/downloads
    

  • Copy a file from vagrant guest to host (via default vagrant port 2222, check it with $ vagrant port):

    $ scp -P 2200 vagrant@127.0.0.1:/vagrant/test.file .
    

  • Copy/Clone/Duplicate a box (https://www.sparxsys.com/blog/how-copy-or-clone-vagrant-box):

    $ vagrant halt
    $ vagrant package --output new_box_name.box
    $ mv new_box_name.box /home/user/path/to/new/location
    $ cd /home/user/path/to/new/location
    $ vagrant init
    $ vi Vagrantfile
        > ...
        > # Every Vagrant development environment requires a box. You can search for
        > # boxes at <https://vagrantcloud.com/search>.
        > config.vm.box = "new_box_name.box"
        > config.vm.box_url = "file:///home/user/path/to/new/location/new_box_name.box"
        > ...
    $ vagrant up
    

Boxes

Vagrant uses a base image to quickly clone a virtual machine. These base images are known as "boxes" in Vagrant. Boxes are globally stored for the current user. Each project uses a box as an initial image to clone from, and never modifies the actual base image.

Plugins

  • List all installed plugins:

    $ vagrant plugin list
    

  • Install a plugin:

    $ vagrant plugin install plugin-name
    

  • Remove a plugin:

    $ vagrant plugin uninstall
    

  • Update a plugin:

    $ vagrant plugin update
    

  • Attempt to auto repair a plugin after an improper plugin installation/removal, or by manual manipulation of plugin related files (like the plugins.json data file):

    $ vagrant plugin repair plugin-name
    

  • Remove all installed users plugin information, plugin gems, plugin dependencies, and plugins themselves:

    $ vagrant plugin expunge --reinstall
    

Snapshot

  • Takes a snapshot of the currently managed Vagrant VM, and pushes it onto the snapshot stack:

    $ vagrant snapshot push
    

  • Restore the last snapshot (on the top of the snapshot stack) of the currently managed Vagrant VM:

    $ vagrant snapshot pop
    

  • Save a new named snapshot. If this command is used, the push and pop sub commands cannot be safely used:

    $ vagrant snapshot save vm-name snapshot-name
    

  • Restore a named snapshot:

    $ vagrant snapshot restore vm-name snapshot-name
    

  • List all snapshots taken:

    $ vagrant snapshot list
    

  • Delete a named snapshot:

    $ vagrant snapshot delete vm-name snaphot-name
    

Vagrantfile

  • Validate your Vagrantfile:

    $ vagrant validate
    

  • Vagrantfile example (WIP):

        > # Vagrantfile docs:
        > # - <https://www.vagrantup.com/docs/vagrantfile/>
        >
        > # Set to true and update proxy configuration to use your enterprise http proxy
        > $use_proxy = false
        > $compose_version = "1.24.1"
        >
        > Vagrant.configure("2") do |config|
        >   # <https://github.com/dotless-de/vagrant-vbguest>
        >   # <https://github.com/leighmcculloch/vagrant-docker-compose>
        >   config.vagrant.plugins = ["vagrant-vbguest", "vagrant-docker-compose"]
        >
        >   if $use_proxy
        >     # <https://github.com/tmatilai/vagrant-proxyconf>
        >     config.vagrant.plugins.push "vagrant-proxyconf"
        >     if Vagrant.has_plugin?("vagrant-proxyconf")
        >       config.proxy.http     = "http://100.101.102.103:4242/"
        >       config.proxy.https    = "http://100.101.102.103:4242/"
        >       config.proxy.no_proxy = "localhost,127.0.0.1,.example.com"
        >     end
        >   end
        >
        >   config.vm.box = "generic/gentoo"
        >
        >   config.vm.provider "virtualbox" do |vb|
        >     vb.name = "gentoo-dev"
        >     vb.memory = 4096
        >     vb.cpus = 2
        >     vb.linked_clone = true
        >   end
        >
        >   config.vm.hostname = "gentoo-dev"
        >
        >   # Networking docs:
        >   # - <https://www.vagrantup.com/intro/getting-started/networking.html>
        >   # - <https://www.vagrantup.com/docs/networking/>
        >
        >   # Forward Host ports to VM
        >   config.vm.network "forwarded_port", guest: 80, host: 8080    # Example NGINX
        >   config.vm.network "forwarded_port", guest: 9000, host: 9000  # SonarQube
        >   config.vm.network "forwarded_port", guest: 5432, host: 5432  # PostgreSQL
        >
        >   # Provisioning docs:
        >   # - <https://www.vagrantup.com/intro/getting-started/provisioning.html>
        >   # - <https://www.vagrantup.com/docs/cli/provision.html>
        >   # - <https://www.vagrantup.com/docs/provisioning/>
        >
        >   # Install Docker & Docker Compose
        >   config.vm.provision :docker
        >   # Issue: <https://github.com/leighmcculloch/vagrant-docker-compose/issues/57>
        >   # Segmentation fault when installing docker-compose
        >   # config.vm.provision :docker_compose, compose_version: $compose_version
        >
        >   # Manual docker-compose installation fallback
        >   config.vm.provision "shell", inline: <<-SHELL
        >     if ! which docker-compose ; then
        >       echo Installing docker-compose onto machine...
        >       curl -sSL -o /usr/local/bin/docker-compose-#{$compose_version} https://github.com/docker/compose/rel
        > eases/download/#{$compose_version}/docker-compose-Linux-x86_64
        >       chmod +x /usr/local/bin/docker-compose-#{$compose_version}
        >       ln -s /usr/local/bin/docker-compose-#{$compose_version} /usr/local/bin/docker-compose
        >     fi
        >   SHELL
        >
        >   # Open JDK install example:
        >   config.vm.provision "shell", inline: <<-SHELL
        >     # Install OpenJDK 11 from AdoptOpenJDK
        >     if ! which javac ; then
        >       echo Installing OpenJDK onto machine...
        >       wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -
        >       add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/
        >       apt install -y adoptopenjdk-11-hotspot
        >     fi
        >   SHELL
        >
        >   # SonarQube install example:
        >   config.vm.provision "shell", inline: <<-SHELL
        >     # Deploy SonarQube needed for tests & QA step
        >     (cd /vagrant && docker-compose up -d sonarqube)
        >
        >     # Build steps
        >     /vagrant/clean.sh
        >     echo
        >     /vagrant/build.sh
        >     echo
        >     /vagrant/test.sh
        >     echo
        >     /vagrant/package.sh
        >   SHELL
        >
        > end
    

Troubleshooting

First instinct

  • After a $ vagrant up, if you run into some errors, check that the vagrant plugins described in your Vagrantfile are well installed:

    $ vagrant plugin list
    

  • If so, then try to repair them:

    $ vagrant plugin repair plugin-name
    

  • If not, then install them:

    $ vagrant plugin install plugin-name
    

  • Finally $ vagrant up again.

Be careful with provisions

config.vm.provision execute only once at the first $ vagrant up (see https://www.vagrantup.com/docs/provisioning/).

Guest machine name too long

If to following error shows up:

    > ...
    > Stderr: VBoxManage: error: The specified string/bytes buffer was to small. Specify a larger one and retry. (VERR_CFGM_NOT_ENOUGH_SPACE)
    > VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component ConsoleWrap, interface IConsole

Then it probably means that the name of the VM (by default depending on the folder name where vagrant up is called) is too long:

SSH command responded with a non-zero exit status

Usually this error message just means that a command send via SSH simply failed. But in the case you get this message in particular:

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

setup

Stdout from the command:

Stderr from the command:

bash: line 4: setup: command not found

And if you are using the vagrant-vbguest plugin, then it might be due to a missing package: virtualbox-guest-additions-iso (needed by the vagrant-vbguest plugin). Don't forget to $ vagrant destroy and $ vagrant up after installing the package.


If the problem persist, add config.vbguest.auto_update = false to your Vagrantfile. It will disable the automatic drivers update. Don't forget to $ vagrant destroy and $ vagrant up after modifying the Vagrantfile.

Resize box disk space

For VirtualBox

A method is to resize the base box that will be used by VirtualBox, e.g. with the Ubuntu (xenial) box:

$ vagrant box add ubuntu/xenial64

$ cd $VAGRANT_HOME/boxes/ubuntu-VAGRANTSLASH-xenial64/20170119.1.0/virtualbox

$ VBoxManage clonehd "ubuntu-xenial-16.04-cloudimg.vmdk" "clone-disk1.vdi" --format vdi # <https://gist.github.com/christopher-hopper/9755310>
$ VBoxManage modifyhd "clone-disk1.vdi" --resize 102400                 # (size in MB)
$ VBoxManage clonehd "clone-disk1.vdi" "clone-disk1.vmdk" --format vmdk #
$ mv clone-disk1.vmdk ubuntu-xenial-16.04-cloudimg.vmdk                 # resize vmdk to 50Go

$ rm clone-disk1.vdi # cleanup

In this example the resulting ubuntu-xenial-16.04-cloudimg.vmdk will be smaller than 1 Go, but the VirtualBox based on it will be 50 Go large.


If this cheat sheet has been useful to you, then please consider leaving a star here.