Skip to content
Logo Theodo

Start using Vagrant

Fabrice Bernhard6 min read

I had the chance to spread the good word by talking about adopting DevOps in Symfony projects at the Symfony Live conference. The feedback was very good (for those who attended and have not done so yet, you can give some feedback here: http://joind.in/talk/view/2756) You can also find the slides here: http://www.slideshare.net/mobile/fabrice.bernhard/adopt-devops-philosophy-on-your-symfony-projects and the source code of the slides here: https://github.com/fabriceb/sflive2011-devops)

One of the very good news is that I convinced many people (as observed on twitter) to start using vagrant after the conference. The slides gave a quick introduction, so let me give here a more detailed tutorial on how to start using vagrant.

Introduction to Vagrant

Vagrant is a ruby tool that makes the process of testing your code in a virtual machine VERY easy. You are concerned:

It is quite amazing to see how many people develop on Macs to deploy on Linux systems and don’t use virtual environments. This has two obvious downsides:

Install Vagrant

sudo gem install vagrant

# Install Ruby, Ruby Gems and Vagrant sudo apt-get install rubygems sudo apt-get install ruby-dev sudo apt-get install build-essential sudo gem install vagrant

Add the ruby gems path to your path

PATH=$PATH:/var/lib/gems/1.8/bin

Download and install VirtualBox

echo ‘echo “deb http://download.virtualbox.org/virtualbox/debian maverick contrib” >> /etc/apt/sources.list’ | sudo sh wget -q http://download.virtualbox.org/virtualbox/debian/oracle\_vbox.asc -O- | sudo apt-key add - sudo apt-get update sudo apt-get install virtualbox-4.0 sudo apt-get install dkms

You should now be able to type vagrant in your terminal and see the list of tasks that you can do.

$ vagrant Tasks: vagrant box # Commands to manage system boxes vagrant destroy # Destroy the environment, deleting the created virtual machines vagrant halt # Halt the running VMs in the environment vagrant help [TASK] # Describe available tasks or one specific task vagrant init [box_name] [box_url] # Initializes the current folder for Vagrant usage vagrant package # Package a Vagrant environment for distribution vagrant provision # Rerun the provisioning scripts on a running VM vagrant reload # Reload the environment, halting it then restarting it. vagrant resume # Resume a suspended Vagrant environment. vagrant ssh # SSH into the currently running Vagrant environment. vagrant ssh_config # outputs .ssh/config valid syntax for connecting to this environment via ssh vagrant status # Shows the status of the current Vagrant environment. vagrant suspend # Suspend a running Vagrant environment. vagrant up # Creates the Vagrant environment vagrant version # Prints the Vagrant version information

Now fetch the base Ubuntu Ludic 32 box provided by Vagrant. This make take a few minutes depending on your connection, since it consists in downloading around 700MB

$ vagrant box add base http://files.vagrantup.com/lucid32.box

Finally, to avoid permission problems with folder sharing between your host machine and your virtual environment, I highly recommend using NFS instead of VBox, which is the default protocol used by VirtualBox.

$ sudo apt-get install nfs-common nfs-kernel-server

Test on a first project

I set up a test project so that you can see how it works. Create a new folder called sflive2011vm. We will clone the configuration for our Vagrant Virtual Machine and then clone our actual project inside

$ cd sflive2011vm $ git clone git://github.com/fabriceb/sfLive2011vm.git . $ git clone git://github.com/fabriceb/sfLive2011.git

Now all you have to do to test the project is

$ vagrant up

and after a few minutes, Vagrant will have started a virtual Ubuntu, installed all the packages needed and set up tha machine as described in the Puppet manifest. To verify that everything worked as planned just visit http://127.0.0.1:2011/hello/master

That’s it!

Understand Vagrant

Let us now understand more deeply how Vagrant works:

The base box

The base box is simply a saved hard-disk of a Virtual Machine created with VirtualBox. It can contain anything but it needs at least :

to be boot-strapped by Vagrant and then further configured by a Chef recipe or a Puppet manifest

Vagrantfile

This is the configuration file of Vagrant. The most useful options are port forwarding, provisioning solution (Puppet or Chef) and eventually NFS

Vagrant::Config.run do |config| config.vm.box = “base” config.vm.forward_port(“web”, 80, 2011) config.vm.provision :puppet

config.vm.share_folder(“v-root”, “/vagrant”, ”.”, :nfs => true)

end

Provisioning

The configuration of your VM is coded using Chef or Puppet. This ensures that you will reproduce exactly the same configuration in all your development VMs AND your production environment. Here is the Puppet manifest used in the example:

exec { “apt-get-update”: command => “apt-get update”, path => [“/bin”, “/usr/bin”], }

Package { ensure => installed, require => Exec[“apt-get-update”] }

class lighttpd { package { “apache2.2-bin”: ensure => absent, }

package { “lighttpd”: ensure => present, }

service { “lighttpd”: ensure => running, require => Package[“lighttpd”, “apache2.2-bin”], }

notice(“Installing Lighttpd”) }

class lighttpd-phpmysql-fastcgi inherits lighttpd {

package { “php5-cgi”: ensure => present, }

package { “mysql-server”: ensure => present, }

exec { “lighttpd-enable-mod fastcgi”: path => “/usr/bin:/usr/sbin:/bin”, creates => “/etc/lighttpd/conf-enabled/10-fastcgi.conf”, require => Package[“php5-cgi”], }

notice(“Installing PHP5 CGI and MySQL”) }

class symfony-server inherits lighttpd-phpmysql-fastcgi {

package { [“php5-cli”, “php5-sqlite”]: ensure => present, notify => Service[“lighttpd”], }

notice(“Installing PHP5 CLI and SQLite”) }

class symfony-live-server inherits symfony-server {

file { “/etc/lighttpd/conf-available/99-hosts.conf”: source => “/vagrant/files/conf/hosts.conf”, notify => Service[“lighttpd”], require => Package[“lighttpd”], }

exec { “lighttpd-enable-mod hosts”: path => “/usr/bin:/usr/sbin:/bin”, creates => “/etc/lighttpd/conf-enabled/99-hosts.conf”, require => File[“/etc/lighttpd/conf-available/99-hosts.conf”], notify => Service[“lighttpd”], }

notice(“Installing and enabling Hosts file”) }

include symfony-live-server notice(“Symfony2 server is going live!“)

Take home message

Liked this article?