Getting intimate with Vagrant part I: The Setup

So vagrant is a way to make portable development environments. It is platform agnostic, it fits any need, and the one I can't believe is that it is COMPLETELY free. One would think a technology that cool they would charge for but nooooo. So the basics of Vagrant are this:

  1. You install vagrant
  2. You install your VM software of choice. The default vagrant config likes virtual box ( also free :) ).
  3. You run vagrant init which makes a cookie cutter vagrant config file. ( Written in Ruby ).
  4. You then write a script that installs all the stuff you want. The easiest way to do this is bash but you can use more ruby ( with chef or a tool like puppet ).

So those are the basics . Let's get started!


Once you install vagrant ( which im assuming you can see how to do from the website, pretty simple ), you run the init command: vagrant init. Dont worry about all the boilerplate code in there. You can strip it down to just this:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version.

# Template vagrant configuration file.
Vagrant.configure("2") do |config| = "ubuntu-12.04"
  config.vm.box_url = ""

  # Create a forwarded port mapping which allows access to a specific port :forwarded_port, guest: 80, host: 8080

  # provision using the shell provisioner
  config.vm.provision :shell, :path => ""

As you can see, the code above is only a handful of lines. Let's cover the noteables.

The line just tells vagrant a nickname to use when it refers to your "box".

A box is just a fancy way of saying a server environment that may or may not contain some extra software goodies. A base server template so to speak.

The config.vm.box_url is obviously the URL to the box. There are some official vagrant boxes you can pull from and then there are some that kind people provide us with on their own accord.

The next part is cool: :forwarded_port This line lets you point any arbitrary port, like port 8080 in this case, to port 80 on the virtual box. What that means is you can do something like localhost:8080 in your browser and that will point to http://localhost on your remote. So now you can see your remote in your browser. What's next?

Link your local and remote file system

This part mirrors changes you make in your file system to a directory of your choosing on your server. I would say maybe it would be good to put it in the webroot but I have also seen just the public folder. This step is achieved via a symlink.

#ln -s /source /destination
rm -rf /var/www  
ln -s /vagrant /var/www  

Vagrant will automagically put everything you do in the /vagrant directory on your remote. The first command above removes the default webroot. The next command remakes it as a symlink to the /vagrant folder. Every request will think it's hitting the webroot but really it's going to the /vagrant directory. Pretty spiffy. My last step i'll show you today is a bit of convinience.

Make the local URL pretty

I don't like having to append ports to my URL's. I think it looks bad and it's just inconvinient. This next trick will let you use port 80 to talk to your port 8080. So Nginx or whatever you use thinks it's going to port 80 but really your mac will redirect it to port 8080. Yes I said Mac. This trick is only for the cool kids :).

This last bit of magic uses the ipfw utility on the mac. The command is:

sudo ipfw add 100 fwd,8080 tcp from any to me 80  

Change the ports as you see fit. This utility is like a built in firewall for mac. The man ipfw says it's deprecated but it still works. Im sure you can do this with it's replacement too. This works though so i'm running with it.

The following commands need sudo.

  • To show your firewall entries do:   sudo ipfw list
  • You can clear all the entries with sudo ipfw flush
  • You can delete a specific entry with sudo ipfw delete <id> (where id is the first thing you see on each line when you list them.


In the next article I will show you how to setup Nginx, PHP, MySql, and Node all automatically from a bash provision script. Stay Tuned!