Making a custom Vagrant base box for your PHP projects
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: 192.168.50.2. 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 192.168.50.2 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 install
ing software and moving configuration files into place.
If you check out that bootstrap.sh
file it tells the rest of the story. It:
- Declares a root password of
100rows
for our database’s root user. - Installs a boatload of packages: Nginx, MySQL and also some other things like Tmux for convenience when interacting with the machine later.
- Moves various Nginx config files into place: things relating to PHP configuration, a dummy SSL certificate, as well as a config file that sets up a site called
default
. - Moves some MySQL configuration files into place, and runs a file config/database.sql, which contains a couple of extra commands to grant privileges to the root user and create an empty database called
default
. - Moves some PHP configuration files into place, which includes a liberal
php.ini
file that should allow fairly large files to be uploaded without any problems, and a liberal amount of memory to be available without errors being thrown.
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 192.168.50.2 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"