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:
Now you can navigate into that directory you just cloned:
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 installing 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
100rowsfor 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
- 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
- Moves some PHP configuration files into place, which includes a liberal
php.inifile 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:
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.
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:
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.
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:
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: