I’m Paul Herron and I’m a web developer. I build online applications
with tools like CakePHP and jQuery.

Making a custom Vagrant base box for your PHP projects

by Paul Herron on 04 May 2014

A couple of weeks ago I posted about using Vagrant as a neat way to develop with WordPress: you simply throw in a few configuration files, do vagrant up and your WordPress install is there and ready to use. In that post I mentioned the idea of using a custom Vagrant base box to keep things simple, and I thought that idea was worth exploring in a little more detail.

By default when you do vagrant up it'll pull in a default Ubuntu installation: a virtual machine or "box" it refers to as precise32. One option is to just customise this box each time the machine is provisioned - so if you're doing some WordPress development you'd have to add a long line into your provisioning script along the lines of apt-get install nginx php5 php5-fpm php5-gd php5-mysql etc. This is fine but each time it does that it's going to take 20 minutes or so to provision the machine as it downloads and install some big packages. A much nicer option is to set yourself up a custom box that has a basic Nginx, MySQL and PHP-FPM setup ready to go. You'll install all of these packages once, get everything working nicely, then export this virtual machine out to a .box file that you can reuse in other projects.

I've already done this and put the results on GitHub, and I tend to keep this repo up-to-date with my ideal basic PHP setup. So far it's proved to be a great starting point for a variety of PHP development work: CakePHP, Yii, Laravel, WordPress and more.

You can get the repo by doing:

git clone https://github.com/paulherron/vagrant_precise32_nginx_mysql_php-fpm.git

Now you can navigate into that directory you just cloned:

cd vagrant_precise32_nginx_mysql_php-fpm

Having a look around

It's not too complicated a setup. There's a file called Vagrantfile in there, which is what Vagrant will take its initial instructions from when you fire up the virtual machine. This file declares a couple of key things: firstly that we want to use the precise32 box to start with, which is that default Ubuntu installation. Then for neatness, we want to use a static IP address for the virtual machine: This will mean we'll always know what IP address to navigate to access our website, and that if we're feeling like it we can also declare a neat testing domain by adding something like default.l onto the end of our /etc/hosts file on the host machine, which would let us view the site in the browser by navigating to http://default.l.

Another key thing the Vagrantfile says is that we want to run the script bootstrap.sh when the machine gets provisioned. It's into that script that we put all of our shell commands for apt-get installing software and moving configuration files into place.

If you check out that bootstrap.sh file it tells the rest of the story. It:

Fire it up

You're ready to fire up the virtual machine:

vagrant up

It'll take about 20 minutes to fetch and install all the files, but this will only be a one-time thing.

If you navigate to in your browser you should see some output: "Vagrant is up!". You should also be able to SSH into the box by doing vagrant ssh, but let's stay on the host machine for now.

Package it

This box isn't going to be much use on its own. Our aim is to package it and use it as a starting point for other projects. That's easily done with the following commands:

vagrant package --output precise32_nginx_mysql_php-fpm.box
vagrant box add precise32_nginx_mysql_php-fpm precise32_nginx_mysql_php-fpm.box

These will generate a big binary file called precise32_nginx_mysql_php-fpm.box in the current directory, and register it with Vagrant with a name of precise32_nginx_mysql_php-fpm. When it's done you should see that Vagrant has stored the box file in ~/.vagrant.d/boxes for future use.

Use it

So now you have a base box that you can use in other projects. Your next project will have its own Vagrantfile and in that you can declare:

# A custom base box is used.
# It has nginx, php-fpm and MySQL pre-installed.
config.vm.box = "precise32_nginx_mysql_php-fpm"

If you're feeling fancy you can also upload your box file to your own server (just be sure not to leave sensitive files like SSH keys in your packaged box). You could even share the link with friends if you think they can get some use out of it. Telling Vagrant where to download the box from if it isn't already available locally is just a case of doing:

# Get the custom box from the SHOWstudio CDN if it hasn't already been downloaded.
config.vm.box_url = "http://yoursite.com/boxes/precise32_nginx_mysql_php-fpm.box"

Back to homepage