Windows/Unix development on Mac Part 2: VirtualBox & Vagrant
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).
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
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,
url create additional statements in the Vagrantfile:
name: populates the
config.vm.box 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 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.
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
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.
Drops you into a shell on your VM.
The status of your VM.
Stops the VM (shutdown)
Restarts the VM (reboot)
Puts the VM to sleep
Wakes up a sleeping VM
Stops and deletes all traces of the VM
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
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 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\] '