Windows/Unix development on Mac Part 2: VirtualBox & Vagrant

September 19, 2016 11:17

There is no lack of fine tutorials on the basics of Vagrant (e.g. here), and O’Reilly of course has an excellent introduction (on Amazon here).

Arguably for my immediate tasks at hand I don’t need Vagrant: at the moment I need to create two Unix VMs for a projects I’m working on, and I could do that just fine with the VirtualBox Manager. But at the very least I want to lay out my projects with multiple reproducible projects in mind. A sane layout now could save me untold grief later.

So far none of the tutorials I’ve found has explained what files get created where, especially with regard to how to organize multiple projects and what needs to go in version control. So below is a list of a basic set of working commands and their implications for multiple project management. (At least for my modest use case.)

Since Vagrant is just a front end for VirtualBox (or the VM of your choice), it’s VirtualBox that creates the VM files (including snapshots). So this article consists of:

  • Glossary: some essential terminology
  • Vagrant Commands: a working subset (and VirtualBox’s underlying file activity)
  • Vagrantfile: the config file for your project's VM

Vagrant uses the Vagrantfile in your current folder to configure and launch a VM. This is a well-commented text file --- edit to taste to configure available RAM, shared folders, etc. See the Vagrantfile section below for some additional hints.

VirtualBox can run a ’group’ of VMs — e.g. a web front end Apache VM and a web backend SQL server simultaneously. That has to be set up in the VagrantFile (or in the VirtualBox Manager).


Hashicorp is the San Francisco based company behind Vagrant and other open source projects. See Wikipedia and their home page.

Host: the underlying machine on which VirtualBox runs.

Guest: a VM created and executed by VirtualBox.

Box: an OS instance ready to be installed by your local VirtualBox.


Basic VM creation/management

vagrant –version

The current version. (As of this blog, the current version is 1.8.5.)

vagrant init [name [url]]

“This initializes the current directory to be a Vagrant environment by creating an initial Vagrantfile if one does not already exist.” The Vagrantfile is an ASCII text configuration file.

So this command only creates a Vagrantfile. If supplied, name and url create additional statements in the Vagrantfile:

name: populates the setting. This is the name of the box Vagrant will use when building the guest machine. This should map to the logical name of a locally installed box (run varant box list ) or is an existing box in the Hashicorp Vagrant Atlas). Or if Url is provided, name will be its local name.

url: populates the config.vm.box_url setting. This is the URL from which to download the box.


vagrant init hashicorp/precise64

vagrant up

Vagrant will use the Vagrantfile in the current folder to create a VM or boot an existing one. (Vagrantfile is well commented, but see the Vagrantfile section below for some of the more common settings.) Running vagrant up a second time results in warning messages.

For convenience I use ‘~’, the user’s home folder in Unix/Mac, as a shorthand for the home folder on Windows as well — that is, %HOMEDRIVE%%HOMEPATH%. The home folder for VirtualBox can be changed in the VirtualBox Manager | Preferences | General tab.

When vagrant up is run successfully for the first time, it creates a folder in ~/VirtualBox VMs/Example, and that folder contains:

Example.vbox: the settings file

  • VM.vdi: the virtual disk image
  • Logs: a logs subfolder
  • Snapshots: the snapshot subfolder (created when you take your first snapshot)

The default user/password for your new VM is vagrant, vagrant.

On Ubuntu (and other Xnix VMs?), use sudo for root tasks, and sudo -i for an interactive root session.

On each subsequent vagrant up, vagrant in essence takes the basic box with which you started and uses the contents of Vagrantfile and ~/VirtualBox Vms/Example to fine tune the configuration & mount the virtual disk image.

vagrant ssh

Drops you into a shell on your VM.

vagrant status

The status of your VM.

vagrant halt

Stops the VM (shutdown)

vagrant reload

Restarts the VM (reboot)

vagrant suspend

Puts the VM to sleep

vagrant resume

Wakes up a sleeping VM

vagrant destroy

Stops and deletes all traces of the VM

Vagrant Snapshots

Snapshots record the current state of the VM.

vagrant snapshot push

Take a snapshot and push it onto the snapshot stack

vagrant snapshot pop

Restore the previously pushed VM state. NOTE: it is a bad idea to mix push/pop and save/restore.

vagrant snapshot save NAME

Saves the named snapshot

vagrant snapshot restore NAME

Restores the named snapshot

vagrant snapshot list

Lists the existing snapshots

vagrant snapshot delete NAME

Deletes the named snapshot

Vagrant Export/Import

TODO: needs more detail

vagrant package NAME

Where NAME is the name of an existing VM. Vagrant reports the name and location of the created box.

vagrant box add


Here is some provisioning code I've added to VagrantFile:

config.vm.provision "file", source: "./.bashrc2", destination: "/home/vagrant/.bashrc2"
config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y vim
    echo >>$VHOME/.bashrc "if [ -f $VHOME/.bashrc2 ]; then\n\tsource $VHOME/.bashrc2\nfi"
    chmod 755 $VHOME/.bashrc2

In addition to installing vim, it adds logic to the end of .bashrc such that if .bashrc2 exists, it executes that too. That allows me to have additional configuration without touching .bashrc any further. During provisioning, the .bashrc2 found in the current folder with Vagrantfile is copied to the VM's /home/vagrant.

Here's a .bashrc2

PS1='\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\H: \[\033[01;37m\]\w\n\$\[\033[00m\] '
tabs 4

    Previous    Next