Skip to content

Instantly share code, notes, and snippets.

@nu7hatch
Created October 30, 2012 21:11
Show Gist options
  • Save nu7hatch/3983095 to your computer and use it in GitHub Desktop.
Save nu7hatch/3983095 to your computer and use it in GitHub Desktop.
Vagrant boxes

What is Vagrant? It's a neat command line interface and toolchain at top of VirtualBox, which allows you to create and manage virtual "boxes" - vm instances with stuff configured for your project.

Why is it awesome?

Because you don't have to setup everything for the project every time when hop in, you do it once using one of the base boxes, you package it and populate *.box file across all project members. When you need to add some software (new database, cache soft, etc), you just have to add it once, and ping everyone to update their boxes. Briliant, isn't it?

It works great also with designers and non-technical people, download and setup of a box takes few minutes and they don't have to polute their machines with all the project related software.

Above all, no more excuses "works for me", or "works on development, but not on the production" - as boxes are made to simulate production environment as much as possible.

Initial setup

To work with Vagrant boxes you must obviously install latest version together with VirtualBox.

VirtualBox installation

In case of VirtualBox, most of operating systems makes it easy to install it from the package managers, however here's some detailed quick start guide to installing it on:

Fedora

$ su
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | rpm --import -
$ wget http://download.virtualbox.org/virtualbox/rpm/fedora/virtualbox.repo
$ cp virtualbox.repo /etc/yum.repos.d/
$ yum install VirtualBox-4.1

Ubuntu

TODO...

Mac OS

TODO...

Vagrant is a ruby gem, so it can be installed from there. It should be installed in your system, not related to the project (added to Gemfile and so on):

$ sudo gem install vagrant

Network File System

One more dependency you must have on your machine to work smoothly with Vagrant is nfs. You gonna share your project with boxes using network file system because it's the fastest and the most efficient way to do this.

Instructions for Fedora and generic Linux

$ su
$ yum install nfs-utils
$ echo -e '#!/bin/sh'"\nsystemctl $@ nfs-server.service" > /etc/init.d/nfs
$ chmod +x /etc/init.d/nfs

Now still as root edit /etc/hosts.deny and add following stuff:

portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL

Also add following lines to /etc/hosts.allow:

portmap: 127.0.0.1, 33.33.33.0/255.255.255.0
lockd: 127.0.0.1, 33.33.33.0/255.255.255.0
rquotad: 127.0.0.1, 33.33.33.0/255.255.255.0
mountd: 127.0.0.1, 33.33.33.0/255.255.255.0
statd: 127.0.0.1, 33.33.33.0/255.255.255.0

Ubuntu

TODO...

Mac OS

TODO...

Building custom boxes

There's few ways to build custom boxes, but I'm nice enough to free you from all the pain of creating them and digging into all the quirks. Feel free to use one of the base boxes I've created:

Ubuntu Precise Pangolin Server x64 - Barebones:

https://dl.dropbox.com/s/n3pl5ginnb7fsrk/ubuntu-precise-server-x64-barebones.box?dl=1

Ubuntu Precise Pangolin Server x64 - Ruby Setup: RVM with Ruby 1.9.3 and Rails 3.2.6, MySQL 5.5, SQLite 3.0 and Redis 2.2:

https://dl.dropbox.com/s/pv4hs8d2ay3ylu7/ubuntu-precise-server-x64-rubies.box?dl=1

Ubuntu Precise Pangolin Server x64 - Ruby Web Development Setup 1: RVM with Ruby 1.9.3 and Rails 3.2.6, MySQL 5.5, SQLite 3.0 and Redis 2.2, Xvfb, Firefox 14:

https://dl.dropbox.com/s/zofltldf77gg0u6/ubuntu-precise-server-x64-rubies-xvfb-ff.box?dl=1

Ubuntu Precise Pangolin Server x64 - Ruby Web Development Setup 2: RVM with Ruby 1.9.3 and Rails 3.2.6, MongoDB 2.0, SQLite 3.0 and Redis 2.2, Xvfb, Firefox 14:

https://dl.dropbox.com/s/9jgj6adj4mumom3/ubuntu-precise-server-x64-rubies-mongo-xvfb-ff.box?dl=1

To build your custom box based on one of listed above, run the following:

$ vagrant box add {box_name} {box_url}

Explicit example:

$ vargant box add myappbox https://dl.dropbox.com/s/n3pl5ginnb7fsrk/ubuntu-precise-server-x64-barebones.box?dl=1
$ vagrant init myappbox
$ vagrant up
$ vagrant ssh
... add things you need to the box
$ vagrant package -o ubuntu-precise-server-x64-myappbox.box

Now upload somewhere your box file, add it as config.vm.box_url to Vagrantfile of your application and populate it. Every time you need to add something new, just run from your app's directory:

$ vagrant up && vagrant ssh
... add things
$ vagrant package -o ubuntu-precise-server-x64-myappbox.box

Now of course you must re-upload it and tell all your team members to remove old box:

$ vagrant box destroy && vagrant box remove myappbox
$ vagrant up 

Easy peasy!

Box notes

Except barebones box, all contain a notes file in /home/vagrant/BOX_NOTES.md. Every time you install new software on the box you should add it to that file so everyone can know what's in there. Write down extra information as user names and passwords to services as well. Whenever you can, set the service up with blank password and default user name.

Building with Puppet or Chef

There's also harder way, which requires using Puppet or Chef with one predefined box. But in my oppinion that way sucks, it's better to have up and ready instance and update it from time to time than deal with another bunch of problems related to devops tools, especially when there's no too much people willing to solve such problems in our office.

Configuring application

When your application dedicated box is set up and uploaded, you can configure your app with Vagrantfile, which goes to project root directory. It's all documented so you should have no problems with customization.

Multiple boxes

Vagrant allows you to configure multi-vm environment. You can use more than one box per application, for example if you need a different box for workers and web app, or separate database box. It's great way to test architecture or run real life load tests. You will find more information how to do it on this Vagrant Documentation page.

Working with Vagrant

Now you can hop in the project with no fuss. You can up and down your instances and remotely execute commands on the box. The project root directory will be mounted with read-write access on the box so any change you make on our machine will be instantly visible there. So here's the summary...

To start the box run:

$ vagrant up

NOTE: The vagrant up command generates .vagrant dotfile, which should be ignored by the SCM. Remember to add this file to your .gitignore.

To stop execute:

$ vagrant halt

To execute commands on the box run:

$ vagrant ssh
vagrant@vagrant:~$ cd myapp
vagrant@vagrant:~$ bundle
vagrant@vagrant:~$ rails s

Thanks to the port forwarding settings you can view the page on your local browser, using traditional `http://localhost:3000/ address.

Summarazing, you edit files with your local editor, you view results with your local browser, the only thing you use remotely is a vagrant shell.

Editor integration with SSH

If your editor is integrated with command line tools (like vim, emacs) you can wire it to remote shell too. Then just add vagrant key to your SSH configuration:

$ wget https://raw.github.com/mitchellh/vagrant/master/keys/vagrant
$ cp vagrant ~/.ssh/vagrant.pem

And write down configuration for the particular connection in your ~/.ssh/config, for example:

Host myapp
HostName 33.33.33.10
Port 22
User vagrant
IdentityFile ~/.ssh/vagrant.pem

Try it out with:

$ ssh myapp

If it works, you can wire it with your editor, you should already know how to do this with your editor :P.

Troubleshooting

It may happen that you'll get the following error message when mounting NFS folder:

Mounting NFS shared folders failed. This is most often caused by the NFS
client software not being installed on the guest machine. Please verify
that the NFS client software is properly installed, and consult any resources
specific to the linux distro you're using for more information on how to
do this.

This error means that there's something wrong with NFS client configuration on the box system. It may be also caused by udev net persistency rules, in that case you disable them on the box. Note that box is up and running, only without access to the shared folder, so runn the following stuff to make it work:

$ vagrant ssh
vagrant@vagrant:~$ sudo su
root@vagrant:/home/vagrant# echo -n > /etc/udev/rules.d/70-persistency-net.rules
root@vagrant:/home/vagrant# echo -n > /etc/udev/rules.d/75-persistency-net-generator.rules
root@vagrant:/home/vagrant# exit
vagrant@vagrant:~$ exit
$ vagrant halt && vagrant up

This situation may also happen if you didn't set up hosts.allow and hosts.deny files correctly or you changed ip address of the box in Vagrantfile. Eventually the firewall defined in iptables may be source of this problem. The most nuclear solution is to disable iptables, here are instructions for Fedora:

$ su
$ service iptables stop
$ chkconfig iptables off

For any other problems check the abyss of teh internetz :P.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment