Setup a Basic PHP Development Environment With Vagrant and Chef-solo

So there are plenty of posts about this out there already. And this is nothing new i guess. But i am going to post it anyway. This weekend i spend some time playing with vagrant. And every setup guide seemed to be missing some steps the make the whole process a bit of a hassle. So i compiled my own steps in the post below. The goal was to create a basic Debian box for my PHP development. From which i could serve my local development files.

So to start of we need some packages.


To create the virtual development image

NFS packages

To make sharing files between host and guest easy as pie


To package the virtual image and manage newly created box

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

Now is a good moment to download any Linux distro you want. I chose Debian. As it´s the most common in my day to day work.

$ wget

Now launch virtualbox and create a new virtual machine. Just do what you normally do when you create a VM. But make sure to choose VMDK `Virtual Machine Disk´ as the format. The rest should be ok. When the VM is created start it up and choose the freshly downloaded Linux ISO to start the installation.

I only installed the base system + the SSH server. And when that’s all done. And the VM is running. Login as root and install some packages vagrant needs.

$ apt-get install sudo ruby ruby-dev libopenssl-ruby rdoc ri irb build-essential ssl-cert curl rubygems puppet

I won’t be setting up a Chef server to manage the vagrant images. But i will be using Chef-Solo to manage installing packages. So let’s install Chef.

install chef

Setup the opscode package repositories for APT

$ echo “deb `lsb_release -cs`-0.10 main” | tee /etc/apt/sources.list.d/opscode.list
$ gpg –keyserver –recv-keys 83EF826A
$ gpg –export | tee /etc/apt/trusted.gpg.d/opscode-keyring.gpg > /dev/null

And finally install the opscode keymanager and and of course Chef.

$ apt-get update
$ apt-get install opscode-keyring
$ apt-get install chef

The installer will ask for the chef URL. I used none because i will be using chef solo

Now we need to add a user for vagrant to connect with.

$ adduser vagrant
passwrd : vagrant
$ groupadd admin
$ usermod -a -G admin vagrant

Make sure the admin users can sudo without a password.

$ visudo

Disable DNS for the SSH server. This should be a performance gain.

$ vi /etc/etc/ssh/sshd_config
UseDNS no

Change the MOTD to something nice

$ bash -c “echo ‘Sweeet! A Vagrant box cooked by Chef!!’ > /etc/motd”
$ chmod 0777 /etc/motd

Switch to the vagrant user to setup the insecure vagrant public SSH key.

$ su vagrant
$ mkdir -p ~/.ssh
$ chmod 0700 ~/.ssh
$ curl -o ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys

That’s it for the VM. Now it’s time for vagrant to do some magic. First we need to create a vagrant package from the newly created VM.

$ vagrant package –base devbox
$ mv

Done! Let’s test it.

$ vagrant box add devbox
$ mkdir test && cd test
$ vagrant init devbox
$ vagrant up
$ vagrant ssh

Voila ssh’d into the VM

$ exit
$ vagrant halt
$ vagrant destroy

So that’s all fine and dandy. But a base system with SSH is not that useful. So that’s where Chef comes in. Like i mentioned earlier i won’t be using a Chef-Server. I will be using Chef-Solo. And will be doing a very basic setup.

A Chef install script is called a cookbook. And they can be found all over the place. But the main repository is over here (find more here So in our vagrant folder we create a folder called cookbooks.

$ mkdir cookbooks
$ cd cookbooks

And we install some basic cookbooks. Plus a very simple one i hacked together to install the latest dotdeb package repositories.

$ git clone

This will be enough for now. And will allow for some basic PHP development. To enable these package we have to edit the Vagrantfile file.

$ vi Vagrantfile

Add these lines for apache forwarding and NFS sharing

config.vm.share_folder “www”, “/var/www”, “/dev/location”

uncomment the :hostonly line so we can acces apache from our local box. And setup a hosts file mapping :hostonly, “”
$ sudo echo “” >> /etc/hosts

Configure chef’s cookbook path and add some recipes from the cloned cookbooks.

config.vm.provision :chef_solo do |chef|
  chef.json = {
    "mysql" => {
      "server_root_password" => "somepassword"
      "bind_address" => ""

  chef.cookbooks_path = "cookbooks"

Time to call vagrant again. And this time the startup takes a bit longer. All the selected packages get installed. And once that’s done. And a fresh development box is waiting.

$ vagrant up
$ vagrant ssh

Let’s check PHP

$ php -v
PHP 5.4.6-1~dotdeb.0 (cli) (built: Aug 19 2012 08:45:58)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

What about apache?

$ ps -aux | grep apache
root 790 0.1 0.2 5352 2580 ? Ss 23:40 0:00 /usr/sbin/apache2 -k start
www-data 793 0.0 0.1 5124 1764 ? S 23:40 0:00 /usr/sbin/apache2 -k start
www-data 797 0.0 0.2 546408 2412 ? Sl 23:40 0:00 /usr/sbin/apache2 -k start
www-data 798 0.0 0.2 546408 2404 ? Sl 23:40 0:00 /usr/sbin/apache2 -k start
www-data 811 0.0 0.2 546408 2424 ? Sl 23:40 0:00 /usr/sbin/apache2 -k start

Nice! And Pointing the browser to http://localhost:8080 loads the NFS shared folder up through Apache. That’s it for now. Time to sleep…

comments powered by Disqus