Setting up a WordPress development environment with Vagrant

Now and then I need to set up some simple WordPress websites for friends or relatives.
The setup I used until now was a virtual machine I configured solely for the development of those sites. The idea was that I could easily move around the virtual machine to another laptop when needed.

However, I failed to make good backups of the virtual machine so I was searching for a better alternative for a while now.

One possible solution was to create a development environment in the cloud with Azure but this seemed a bit overkill.

A while ago I already gave Vagrant a try, but it didn’t work out very well (lots of error messages etc…)
However, I decided to try it again and I didn’t encounter any blocking issues this time.

The hard part was configuring a bootstrap file to set up a WordPress environment with the initial database configuration.
The reason for this post is outlining these steps to create a virtual machine with a basic WordPress installation using Vagrant.

If you never used Vagrant before I recommend to follow the “Getting started” page on their website.
If you’re able to run a basic virtual machine (this is where it went wrong with my first Vagrant try) as described on that page, come back and continue with this post here.

 Vagrant file

If you followed along the Getting started page, then a Vagrant file should not be an unfamiliar thing to you.
There are four changes I made to the file but two of them are optional changes.

Enable provisioning with a shell script (mandatory to follow along)
config.vm.provision :shell, path: "bootstrap.sh"
Set the permissions on the shared folder (mandatory)
config.vm.synced_folder ".", "/vagrant", :mount_options => ["dmode=777","fmode=666"]

This is necessary to make sure WordPress has the correct permissions to upload files. As you may notice the settings above are unsecure (777 setting) but for development this shouldn’t be an issue.

I used a Ubuntu box as setup
config.vm.box = "ubuntu/trusty64"
Create a private network (optional)
config.vm.network "private_network", ip: "192.168.100.2"

I then created an entry in my hosts file to map this IP to a specific URL (dev.caffeinetocode.be for example)

 Bootstrap file

This file is the shell script we configured in the Vagrant file when we enabled provisioning.

First, let me show you the complete file.
Almost everything of the configuration below is copied from the WordPressWithVagrant repository on GitHub, but I needed to make some additional tweaks to get it work.

#!/usr/bin/env bash

sudo debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password password averycomplexpassword'
sudo debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password_again password averycomplexpassword'
sudo apt-get update
sudo apt-get -y install mysql-server-5.5 php5-mysql apache2 php5

if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant/public /var/www

  a2enmod rewrite

  sed -i 's:<Directory /var/www/>:<Directory /vagrant/public/>:' /etc/apache2/apache2.conf
  sed -i 's:/var/www/html:/vagrant/public:' /etc/apache2/sites-enabled/000-default.conf
  service apache2 restart
fi

if [ ! -f /var/log/databasesetup ];
then
    echo "CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'wordpresspass'" | mysql -uroot -paverycomplexpassword
    echo "CREATE DATABASE test" | mysql -uroot -paverycomplexpassword
    echo "GRANT ALL ON test.* TO 'wordpressuser'@'localhost'" | mysql -uroot -paverycomplexpassword
    echo "flush privileges" | mysql -uroot -paverycomplexpassword

    mysql test -u root -prootpass < /vagrant/wp_setup/database/initial_database_setup.sql

    touch /var/log/databasesetup
fi

Let’s review each step.

sudo debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password password averycomplexpassword'
sudo debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password_again password averycomplexpassword'

After installing MySQL it will ask some questions to complete the installation.
Because we don’t want to enter these details over and over again when booting up the virtual machine we can use the command debconf-set-selections which allows for easier installation.

So here we tell MySQL to use the password averycomplexpassword for the root user when installing MySQL.

sudo apt-get update
sudo apt-get -y install mysql-server-5.5 php5-mysql apache2 php5

Next we will update all installed packages and install the required components the run a WordPress site.
No further explanation needed I guess.

if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant/public /var/www

  a2enmod rewrite

  sed -i 's:<Directory /var/www/>:<Directory /vagrant/public/>:' /etc/apache2/apache2.conf
  sed -i 's:/var/www/html:/vagrant/public:' /etc/apache2/sites-enabled/000-default.conf
  service apache2 restart
fi

By default, Vagrant provides a shared folder (/vagrant) which is accessible by the host and guest.
I’ve created an extra folder inside the vagrant folder where all my WordPress files will be stored.

In this part it will create a symbolic link from the public folder in the shared folder to the /var/www folder.
It also changes two configuration files of Apache to use the shared Vagrant folder as web root.

It then restarts the Apache service.

if [ ! -f /var/log/databasesetup ];
then
    echo "CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'wordpresspass'" | mysql -uroot -paverycomplexpassword
    echo "CREATE DATABASE test" | mysql -uroot -paverycomplexpassword
    echo "GRANT ALL ON test.* TO 'wordpressuser'@'localhost'" | mysql -uroot -paverycomplexpassword
    echo "flush privileges" | mysql -uroot -paverycomplexpassword

    mysql test -u root -prootpass < /vagrant/wp_setup/database/initial_database_setup.sql

    touch /var/log/databasesetup
fi

Next and final step is setting up the database.
When configuring WordPress for the first time you will need to uncomment the following line:

mysql test -u root -paverycomplexpassword < /vagrant/wp_setup/database/initial_database_setup.sql

This SQL file will be created after you runned through the WordPress installation.
But basically this part of the script checks if there’s a certain file available which should have been created the first time. We do this check because we don’t want to run this part of the script again when resuming or reloading the configuration.

It creates a new MySQL user which gets access to our database.

If everything went well you should be able to access your WordPress site by the specified IP-address in your Vagrant file (or URL if you also configured it in your hosts file).

Creating a initial SQL script for WordPress

After completing the installation step of your WordPress site, access your VM with

vagrant ssh

Enter the following command in the command prompt

mysqldump -h localhost -u root -paverycomplexpassword test (this is the database name) > initial_database_setup.sql

Now copy this file to a folder inside your Vagrant folder (I used wp_setup/database).
Uncomment the line in the script as stated previously and destroy your VM to test if everything works.

vagrant destroy

Restart your VM with

vagrant up

And when everything is booted up, you should be able to access your WordPress site without any additional configuration required!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s