Making a Vagrant box for Rails

me@kevinbaugh.com

Kevin Baugh

Why Should I Care?

A Few Things To Get

What is VirtualBox?

What Is VirtualBox?

  • VirtualBox is by Oracle Systems
  • Allows you to host another machine on your computer.
  • This could be a server for development, a windows box, or really whatever you want.

What About Vagrant?

What about Vagrant?

  • Vagrant is a way to make your virtualboxes (and other virtual machines) portable and easy to share. 
  • There's a configuration file called "Vagrantfile" that handles all of the configuration needed for your box.
  • Has built in support for both Chef and Puppet.
  • Can be deployed in a Virtual Environment like Virtualbox, or can be deployed to heroku/amazon.

Chef?

Chef?

  • Chef is a way to auto run setup scripts when booting up a virtual machine.
  • Written in "recipes," this code is easily shared and modal.
  • Smarter people than you have written "cookbooks" full of "recipes" to make your life easier.

Let's Get Started!

> vagrant plugin install vagrant-vbguest
> vagrant plugin install vagrant-librarian-chef

First, we're going to install some vagrant plugins to make our lives easier.

Why did we just do that?

  • The vbguest plugin helps your virtual machine talk to your computer a lot easer.
  • The librarian-chef plugin helps you not have to download all of your cookbooks and makes them a lot easier to store.

Basic of basic setup

> cd project_name
> mkdir vagrant

First we're going to make the folder structure. Which is a project folder with a vagrant folder inside of it.

Then, cd into the vagrant folder, and run "vagrant init," which will make a Vagrantfile.

> cd vagrant
> vagrant init

Finally, create a file called "Cheffile" 

> touch Cheffile

What...what did we just do?

  • The folders are pretty self explanatory...come on.
  • "vagrant init" creates a Vagrantfile, which is what Vagrant uses for configuration.
  • Creating the Cheffile is part of the librarian-chef plugin.
    • It lets you define dependencies in Chef like a Gemfile does for Ruby.

Cheffile Contents

First, we need to define where exactly all these chef files are going to be coming from.

site "http://community.opscode.com/api/v1"

Now, what cookbooks are we going to need?

cookbook 'apt'
cookbook 'build-essential'
cookbook 'mysql', '5.5.3'
cookbook 'ruby_build'
cookbook 'nodejs', git: 'https://github.com/mdxp/nodejs-cookbook'
cookbook 'rbenv', git: 'https://github.com/RayMangum/chef-rbenv'
cookbook 'vim'

What is this doing?

  • The source says "download all files from this location"
  • The files that you're downloading are setup scripts that other have written to make your life way, way easier.
    • So, you just define what you're going to be installing.

Cheffile

site "http://community.opscode.com/api/v1"

cookbook 'apt'
cookbook 'build-essential'
cookbook 'mysql', '5.5.3'
cookbook 'ruby_build'
cookbook 'nodejs', git: 'https://github.com/mdxp/nodejs-cookbook'
cookbook 'rbenv', git: 'https://github.com/RayMangum/chef-rbenv'
cookbook 'vim'

Now to the Vagrant File!

Vagrant creates a file that we can use to define our VirtualBox configuration.

They were kind enough to fill it with helpful comments and setup examples.

...Erase it all. We're doing this from scratch.

First, the skeleton structure

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

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

end

Everything is going to go between the "do" and the "end"

Now, to define a base box

# Use Ubuntu 14.04 Trusty Tahr 64-bit as our operating system
config.vm.box = "ubuntu/trusty64"

A base box has all of the bare bones setup you're going to need.

It shortcuts having to setup absolutely everything.

More base boxes!

Give Ourselves A Little

More Wiggle Room

Let's up the memory a little bit on our box.

  # Configurate the virtual machine to use 2GB of RAM
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end

Match up Port 3000

Now we can match up port 3000 on the server to the same port on your computer so localhost:3000 will work the same (yay, Rails).

# Forward the Rails server default port to the host
config.vm.network :forwarded_port, guest: 3000, host: 3000

Mounting on the Wall

Now, we can mount our projects folder straight into the server.

# From where, to where?
config.vm.synced_folder "../", "/mnt"

This means, anything that's one folder up from your Vagrantfile location will be available on the server at "/mnt"

Too Many Cooks

Now it's time to setup your Chef configs. 

# Use Chef Solo to provision our virtual machine
config.vm.provision :chef_solo do |chef|

end

First, the wrapper.

Too Many Cooks

Now, all our cookbooks (to add an individual recipe instead of the default, use ::)

  # Use Chef Solo to provision our virtual machine
  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks", "site-cookbooks"]

    chef.add_recipe "apt"
    chef.add_recipe "nodejs"
    chef.add_recipe "ruby_build"
    chef.add_recipe "rbenv::user"
    chef.add_recipe "rbenv::vagrant"
    chef.add_recipe "vim"
    chef.add_recipe "mysql::server"
    chef.add_recipe "mysql::client"

  end

Too Many Cooks

  • Ruby Version 2.1.2
  • The bundler gem and rails for this version of ruby.
    • If you already have a Rails project, you don't need to add rails.
  • A blank mysql root password

Finally, we tell Chef what exactly we want installed. Which is:

Too Many Cooks

    chef.add_recipe "mysql::client"

    # Install Ruby 2.1.2 and Bundler
    # Set an empty root password for MySQL to make things simple
    chef.json = {
      rbenv: {
        user_installs: [{
          user: 'vagrant',
          rubies: ["2.1.2"],
          global: "2.1.2",
          gems: {
            "2.1.2" => [
              { name: "bundler" },
              { name: "rails" }
            ]
          }
        }]
      },
      mysql: {
        server_root_password: ''
      }
    }
  end

All Done With Setup

That's really it when it comes to writing stuff. 

Start 'er Up

Now that we have everything defined, we need to actually build up the box and start it.

> vagrant up

This will take FOREVER, so go make yourself a sandwich or something.

Getting Into Your VirtualBox

To access your server, just run the following command (the password is "vagrant" in case it asks):

> vagrant ssh

Installing Gems and Such

If you already have a Gemfile, just do the following to install any dependencies.

(This assumes your Gemfile is at /project_name/Gemfile)

> cd /mnt
> bundle install
> rbenv rehash

Running a Rails Server

To run the Rails server, there is one thing you have to do different.

> rails server -b 0.0.0.0

You'd still access this from http://localhost:3000 because of the port forwarding.

0.0.0.0 means that Rails is listening on all interfaces, not just the loopback interface. So that pushes to 127.0.0.1(or localhost) on your local machine.

Now, Even Easier

I've made a github repo with all this in it.

The master branch is a boxed up version of this server, so just run vagrant up and after the initial download it shouldn't take too long to up.

Last, But Not Least

We need a way to stop our server when it's not in use, so you can use either of the following:

> vagrant halt

This will shut down your server. If you want to go scorched earth on it and completely destroy everything, do:

> vagrant destroy

Questions?

Techrangers are hiring!

Thanks for listening!

You can access this slideshow at 

http://slides.com/loraxx753/deck

University Meetup Group

By Kevin Baugh

University Meetup Group

  • 715