Let's Talk About Vagrant

Problem: Works on my box, won't fix!

Troll

Solution: Vagrant?

Benefits of using Vagrant

Vagrant Boxes

Project Setup

Vagrant::Config.run do |config|
  config.vm.box = "base"
end

Wait there's more!

Most projects will require some type of database or web server. This is where provisioning comes into play. We need to now setup the VM with apache and MySQL as well as anything else that our project needs.

Provisioning with Chef-Solo

What is provisioning?

What is Chef-Solo?

Example section in your Vagrantfile

...
  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks","site-cookbooks"]
    chef.add_recipe "apt"
    chef.add_recipe "openssl"
    chef.add_recipe "apache2"
    chef.add_recipe "mysql"
    chef.add_recipe "mysql::server"
    chef.add_recipe "php"
    chef.add_recipe "php::module_apc"
    chef.add_recipe "php::module_curl"
    chef.add_recipe "php::module_mysql"
    chef.add_recipe "apache2::mod_php5"
    chef.add_recipe "apache2::mod_rewrite"
    chef.json = {
        :mysql => {
            :server_root_password => 'root',
            :bind_address => '127.0.0.1'
        }
    }
  end
...

Port Forwarding

SSH into the VM

Suspend, Halt, or Destroy?

Suspend, Halt, or Destroy?

Suspend, Halt, or Destroy?

Rake

Rake, run commands on Host Machine

require 'vagrant'

desc "Run vagrant up"
task :up do
  puts "starting to run vagrant up"
  env = Vagrant::Environment.new
  env.cli('up')
  puts "complete"
end

desc "Run vagrant halt"
task :halt do
  puts "Graceful shutdown of server starting"
  env = Vagrant::Environment.new
  raise "Must first run rake up" if !env.primary_vm.created?
  rasie "There is no VM running" if env.primary_vm.state != :running
  env.cli('halt')
  puts "Shutdown of server complete"
end

Rake, run commands on Guest Machine

...

# Symfony tasks that are all run on the VM
namespace 'symfony' do
  # cache tasks
  namespace 'cache' do
    desc "Clear the symfony cache"
    task :clear do
      puts "clearing symfony cache"
      env = Vagrant::Environment.new
      raise "Must first run rake up" if !env.primary_vm.created?
      rasie "There is no VM running" if env.primary_vm.state != :running
      env.primary_vm.channel.execute('cd /vagrant; php symfony cc');
      puts "cahce has been cleared"
    end
  end
end

...

Rake, run commands on Guest Machine with sudo

...

desc "There's this command"
task :clear do
  puts "Destroy!"
  env = Vagrant::Environment.new
  raise "Must first run rake up" if !env.primary_vm.created?
  rasie "There is no VM running" if env.primary_vm.state != :running
  env.primary_vm.channel.sudo('rm -rf /');
  puts "Your VM has been destroyed"
end

Let's Talk About Symfony

What is symfony?

PHP MVC framework.

Update a symfony 1.4 project to use Vagrant

Assumptions:

Let's install some cookbooks

Since the server requires us to have things like apache and MySQL, we need to download those cookbooks

Cookbooks that you need to put in SF_ROOT_DIR/cookbooks

Download at: http://community.opscode.com/

Use knife to download them:

knife cookbook site download COOKBOOK_NAME

We need to create a site cookbook

This cookbook is for this site only. It will contain recipes on setting up the vhost and other information, but that comes later. We first need to create the cookbook.

knife cookbook create Symfony -o site-cookbooks/

Update the Vagrantfile

Theres a few things we need to update in the Vagrantfile

  ...
  config.vm.network :hostonly, "192.168.33.10"
  config.vm.forward_port 80, 8000
  config.vm.share_folder "www-data", "/vagrant", ".", :nfs => true
  ...

Update the Vagrantfile (continued)

  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks","site-cookbooks"]
    chef.add_recipe "apt"
    chef.add_recipe "openssl"
    chef.add_recipe "apache2"
    chef.add_recipe "mysql"
    chef.add_recipe "mysql::server"
    chef.add_recipe "php"
    chef.add_recipe "php::module_apc"
    chef.add_recipe "php::module_curl"
    chef.add_recipe "php::module_mysql"
    chef.add_recipe "apache2::mod_php5"
    chef.add_recipe "apache2::mod_rewrite"
    chef.json = {
        :mysql => {
            :server_root_password => 'root',
            :bind_address => '127.0.0.1'
        }
    }
  end

Vagrant UP!

Now just run vagrant up and within a few minutes it will bootup. Now just head over to http://127.0.0.1:8000

You should notice that there are a few issues with this. First off, where's the symfony app? You should see just the default apache "It Works" page.

We need to update our cookbook that we have in the site-cookbooks directory.

Vagrantfile

We need to enable our cookbook in our Vagrantfile. Find the section where you have all your chef-solo configuration.

    ...
    chef.add_recipe "Symfony"
    ...

Let's update some code

SF_ROOT_DIR/site-cookbooks/Symfony/recipes/default.rb

execute "disable-default-site" do
  command "a2dissite default"
end

web_app "symfony" do
  application_name "symfony-app"
  docroot "/vagrant/web"
end

What does all that mean?

It says:

So how do we setup a symfony vhost?

When chef creates your vhost, it looks for a file in the template directory called web_app.conf.erb.

SF_ROOT_DIR/site-cookbooks/Symfony/templates/default/web_app.conf.erb

<VirtualHost *:80>
  DocumentRoot <%= @params[:docroot] %>
  <Directory <%= @params[:docroot] %>>
    Options +FollowSymLinks +ExecCGI
    AllowOverride All
    Allow from All
    DirectoryIndex index.php
  </Directory>
  Alias /sf /vagrant/lib/vendor/symfony/data/web/sf
</VirtualHost>

Symfony on Vagrant, ENGAGE!

Resources/More Info