Setting up a Rails 3 virtual machine using Vagrant and VirtualBox
I recently started bringing other developers on board to help me with a project that up until then I had been the sole developer on. I already had some rudimentary installation instructions that I had updated on occasion as I was originally developing the application, but it turns out that all the developers experienced problems of one kind or another while following along on their own development machines. Although I had recommended using RVM to at least isolate the application gem bundle, it was clear that there were other per-machine libraries and dependencies that were not being accounted for. So, I decided to include instructions on setting up a virtual machine which would hopefully alleviate these issues. My problem with VMs in general though, especially ones that you want to spin up and tear down quickly, is that it’s still possible for everyone involved in the project to be using a different VM manager and linux distro, and thus a different package manager and standard lib setup, and you still need to do a lot of setup after the fact to get all the necessary components to work. Enter Vagrant.
Vagrant is “a tool for building and distributing virtualized development environments.” It’s a command line based utility (Ruby gem) that helps you setup and teardown VMs using Oracle’s VirtualBox virtualizer. And since both Vagrant and VirtualBox work on Linux, Mac OSX and Windows, it’s perfect for distributed development teams.
The following write-up is based on a nearly year-old article by Pete McBreen, but updated for the most recent release of Vagrant. We’re also going to install Imagemagick and the Nokogiri prerequisites. Note that this particular set of instructions doesn’t include the setup of any database other than SQLite (i.e. MySQL or Postgres), but hopefully you can figure that on your own if you need to after following along with the rest of this walk through.
From the console, run the following commands in the directory where you want your VM to run from:
$ gem install vagrant
$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
$ vagrant init
The first command installs the Vagrant gem, which includes the
vagrant utility. The second command prepares a new VM based on Ubuntu and downloads the source (if necessary) from the specified URL. The last command generates some files into the current folder that we will use to provision the VM.
Edit the newly generated Vagrantfile file to this:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant::Config.run do |config|
config.vm.box = "lucid32"
config.vm.provision :chef_solo do |chef|
# Grab the cookbooks from the Vagrant files
chef.recipe_url = "http://files.vagrantup.com/getting_started/cookbooks.tar.gz"
# Tell chef what recipe to run. In this case, the `vagrant_main` recipe
# does all the magic.
config.vm.forward_port 80, 8080
config.vm.network :hostonly, "192.168.10.200"
This tells vagrant to use the lucid32 VM we just prepared, to include the “solo” recipe from the chef project which will give us some useful webdev tools, to port forward apache’s default port to a higher port, and finally to make the machine accessible on the specified IP address from the host machine. The IP address can be whatever you want it to be, as long as it’s in a different subnet than your host machine.
Save your changes and close the file. Back at the console, run:
$ vagrant up
This starts up the server via VirtualBox. Now log into the VM:
$ vagrant ssh
You won’t need any special username or password to SSH in, nor will you need one for any of the next steps.
Start setting it up. Note that all of these commands will be run inside the VM that we are SSH’d into. Your host machine will be unaffected.
$ sudo apt-get -y install git-core
$ sudo apt-get -y install curl
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
$ source ~/.profile
$ rvm requirements
Look for output from that last command that starts with “# For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following:” It will probably look something like this:
$ sudo apt-get install -y build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion
Paste it into your terminal and run it to install any missing dependencies.
Make sure everything is working OK so far with:
$ rvm info
Next, setup Ruby and Bundler on the VM:
$ rvm install 1.9.2
$ rvm use 1.9.2 --default
$ gem update --system
$ gem install bundler
We’re using Nokogiri for parsing some HTML, but there are some prereqs that we’ll need to install before we install the gems that use it (via our gem bundle):
$ sudo apt-get install -y ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8
$ sudo apt-get install -y libreadline-ruby1.8 libruby1.8 libopenssl-ruby
$ sudo apt-get install -y libxslt-dev libxml2-dev
Installing Imagemagick is a bit simpler:
$ sudo apt-get install -y imagemagick
Configure Git and SSH:
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "email@example.com"
Note: Use the same email address that you have registered at Github
Now we need to add your SSH key to the Git repository. Run:
$ cat id_rsa.pub
Now copy the output of that to the clipboard, login to your Github account, click the “Account Settings” icon, then the “SSH Keys” link, click “Add New SSH Key”, give it a title and paste your key into the “Key” box, then save it.
Now we will test that it works
$ ssh -T firstname.lastname@example.org
You should see a message like:
Hello, username! You’ve successfully authenticated, but GitHub does not provide shell access.
Now configure Git:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
The virtual folder
/vagrant on the VM is linked to the same folder from which you ran
vagrant init and
vagrant up. We will place the project files there so we can interact with them in the host system too:
$ cd /vagrant
$ mkdir project
$ cd project
$ git clone ssh://firstname.lastname@example.org/username/your-project.git .
Now edit your database config files as necessary and install the gem bundle:
$ bundle install --without production staging
If that completes w/o error then you can continue with the rest of the configuration process for your application. Once it is setup and your
rails server is running, you can access this VM in the browser on your host computer using the URL http://192.168.10.200:3000.