This is the second post in a series of developing for WordPress in a DevOps friendly way. The other articles:
- Introduction to WordPress and DevOps
- Developing with WordPress and Vagrant
- Grunt Automation for WordPress developers
- WordPress configuration management
Lets recap a bit to last post in this series. Vagrant is a piece of software that will help you automate the creation of Virtual Machines right on your development computer. The benefits of running your WordPress project inside a Vagrant machine are that (1) you can use the same software stack of operating system, web server and database as you will use in production and (2) you can make changes to the development environment without affecting the rest of your computer or any other projects. Lastly (3) it’s super easy to make sure that all developers working on the same project actually has the exact same environment.
In this post we will get a bit practical and demonstrate how Vagrant works. We will set up a WordPress installation inside a Vagrant machine and then surf to it from your development computer and we will automate as much of the WordPress installation as possible. In fact, it’s so automated out of the box that you will only need to type five (5) commands to get your WordPress install up and running. We’ll also touch briefly on the tools Grunt and wp-cli, but more in depth articles on those tools will follow soon.
Preparing
Before we can do anything else, we need to get Vagrant and a Virtual Machine manager installed on our development computer. This step depends on the OS on your machine and as the Vagrant documentation says, it’s extremely easy. Head over to their downloads page and install it using standard procedures on your OS.
The same goes for the Virtual Machine Manager. Vagrant supports VirtualBox and VM-Ware as well as a few other possible backends. I’m a long big fan of VirtualBox so that’s what I recommend. Head on over to the VirtualBox downloads page and get the version that’s right for your computer. Install it using standard procedures on your OS.
We also want to install a plugin to Vagrant called host-updater. This plugin will automatically rewrite the hosts file (/etc/hosts) on the host machine, that makes it so much easier to surf to the WordPress installation later on and keep. At the command prompt of your computer type:
[code]
$ vagrant plugin install vagrant-hostsupdater
[/code]
Setting up a remote repository
Clone or copy my Get repository for this blog post, https://github.com/eriktorsner/wordpressvagrant, into a folder on your computer. From now on, we’lll refer to that folder as the project folder. I suggest your start your own remote Git repository (on github or elsewhere) so that you get your project under source code control right from the start. It’s good development practice.
The included files.
As you can see, there are only a handful of files in the code you’ve just copied. Let’s talk about what they do:
- Vagrantfile This file is the main Vagrant configuration file. It defines the virtual machine that we’ll soon fire up. If instructs Vagrant to create a machine with a specific hostname, a specific amount or RAM and disk, what IP-number to use and a few other things. At the top of this file, there are 4 lines of code that needs to be changed to suit your environment, but other than that, you should be able to use this file as is. One of the most important parameters that is defined in this file is “config.vm.box” that tells Vagrant what base image to start with. We’re using “ubunty/trusty64” which gives us a bare bones Ubuntu 64 bit operating system to start with.
- Subfolder vagrant. This subfolder contains some additional settings for Vagrant that is uses during the provisioning phase. We’ll talk more about provisioning further down, but basically it’s a script that is executed the first time we start the virtual machine and that installs “everything else” which in our case means the nginx webserver, MySQL database server, PHP and a bunch of other useful tools.
- package.json is the settings file for the Node Package Manager (NPM). We use NPM to install Grunt and some of it’s dependencies.
- Gruntfile.js is the settings file for the Grunt automation tool. We’ll talk more about Grunt in a later episode, right now it’s enough to know that Grunt can be used to automate things and that we’ll use it to automate WordPress installations.
- .gitignore is simply a file that tells Git what files and folders we want to keep out of version control
- localsettings.json.template In our approach to WordPress we want to automate as much as possible and to do that, we need a place to store things that are unique to this particular environment. Since this file should never be added to Git, I’ve included a template, not the actual file. Any setting that will differ from this development environment we’re currently creating and the live production environment should be captures in this file. In this template file, we have things like URL, path to WordPress, WordPress passwords etc. The parameters in the template happen to nicely align to most default values defined in Vagrantfile and provisioning.
Starting the virtual machine
Before we can start the Vagrant machine for the first time. Open Vagrant file and make sure lines 3-6 have sensible values. Hostname, devdns and testdns should have values that makes sense for your project name and ipnumber should be a unique ip number that is not already used by another virtual machine on your computer.
[code language=”ruby”]
# -*- mode: ruby -*-
# vi: set ft=ruby :
hostname = ‘wpvagrant’
ipnumber = ‘192.168.50.33’
devdns = ‘www.wpvagrant.local’
testdns = ‘test.wpvagrant.local’
[/code]
Once you’ve made those changes, fire up your Vagrant box with this simple command:
[code]
$ vagrant up
[/code]
Now is a good time to grab a cup of coffee. Vagrant will download and install a lot of things. On my computer this process normally takes 5-8 minutes, but it will vary depending on network speed and your computers performance.
Working inside the virtual machine
Once Vagrant has finished it’s setup process we’ll log into the command line shell of the virtual machine. Type the command vagrant ssh and you should be greeted with something like this:
[code]
$ vagrant ssh
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-46-generic x86_64)
* Documentation: https://help.ubuntu.com/
System information disabled due to load higher than 1.0
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
vagrant@wpvagrant:~$
[/code]
An important feature of Vagrant is that it keeps folders on your development computer in sync with a special folder inside the virtual machine. By default, this folder is named vagrant and is located at the root of the file system. Go to that folder and check out the contents, it should match exactly what you see in the project folder on your development computer
[code]
vagrant@wpvagrant:~$ cd /vagrant
vagrant@wpvagrant:/vagrant$ ls -alg
total 52
drwxrwxr-x 1 vagrant 4096 Sep 18 10:07 .
drwxr-xr-x 24 root 4096 Sep 18 10:05 ..
drwxrwxr-x 1 vagrant 4096 Sep 17 18:12 .git
-rw-rw-r– 1 vagrant 216 Sep 18 09:46 .gitignore
drwxrwxr-x 1 vagrant 4096 Sep 18 10:01 .vagrant
-rw-rw-r– 1 vagrant 1461 Sep 18 10:07 Gruntfile.js
-rw-rw-r– 1 vagrant 1079 Sep 17 18:12 LICENSE
-rw-rw-r– 1 vagrant 19 Sep 17 18:12 README.md
-rw-rw-r– 1 vagrant 3995 Sep 18 09:40 Vagrantfile
-rw-rw-r– 1 vagrant 405 Sep 18 09:11 localsettings.json.template
-rw-rw-r– 1 vagrant 354 Sep 17 18:52 package.json
drwxrwxr-x 1 vagrant 4096 Feb 4 2015 vagrant
drwxrwxr-x 1 vagrant 4096 Sep 18 10:08 www
[/code]
Installing WordPress
We are only a few commands away from installing WordPress. First we’ll copy / renamelocalsettings.json.template so that we have a correctly named localsettings file.
[code]
$ cp localsettings.json.template localsettings.json
[/code]
As I wrote above, no actual changes are needed inside this file as long. Next, we’ll use npm to get all the dependencies for Grunt.
[code]
$ npm install
[/code]
Npm takes a few seconds and when it’s finished you should see that you have a new sub folder node_modules in your project folder. And lastly, we’ll use Grunt to install WordPress using a custom Grunt task:
[code]
$ grunt wp-install
[/code]
And that’s it. WordPress should be ready to use. Test it by using a web browser on your desktop and type in the address to your development machine. The default is: http://www.wpvagrant.local (but you’ve might have changed it in the Vagrantfile).
Summary
In this article, we’ve looked at how easy Vagrant can be made part of your development environment, as a side effect you’ve also saw a glimpse of how WordPress installs can be automated using wp-cli and Grunt (more on that in a later post). Since Vagrant has grown in popularity there are many alternative Vagrant default configurations you can use for WordPress development. The one I’ve share is this article is geared towards developing web sites with WordPress, but there are others that are organized to be more suitable for Theme or Plugin development. To mention a few:
- Varying Vagrant Vagrants (https://github.com/Varying-Vagrant-Vagrants/VVV) is the first I encountered that is focused on WordPress. My configuration is based on this.
- VCCW (http://vccw.cc/) is another good option. One of the benefits is that it uses Chef for provisioning rather than a shell script as mine and VVV does.
- dominikzogg/vagrant-php (https://github.com/dominikzogg/vagrant-php) is a generic PHP development environment that supports WordPress among other things. I find this very interesting because it makes it easy to try your application on different versions of PHP, including PHP 7 and HHVM
In the next post in this series, we’ll dive deeper into automating the WordPress installation even further. We’ll look at how to get plugins, themes and settings in place using code rather than manual configuration in the WordPress admin area.
Until then, over to You, let me know what you think in the comments.
WordPress DevOps – The book
I’ve written an ebook on this subject. Released in September this year on Leanpub.com. Expect a 100+ tightly written pages where we walk through the creation of the skeleton of a WordPress based Saas application, connected to Stripe and Paypal with a working deployment process that takes content into account. Just add your billion dollar idea. Jump on over to Leanpub to get your copy.
[wysija_form id=”3″]
Hi Erik, does this work with multiple wp websites?
Hi Mdunbavan,
I’m not 100% sure what you mean with multiple wp websites. Personally I prefer to have one project folder with one accompanying Vagrant box for each website I work with. So if you just keep each site in a separate folder, this approach works.
It’s possible you’re wondering if it’s possible to run multiple WordPress sites in the same vagrant machine, and yes that’s possible as well. The way I’d do it is to put each WP site in a subfolder of /vagrant so that I get /vagrant/site1, /vagrant/site2 etc. Then I’d have to go and change some of the Vagrant provisioning. First, I’d probably add more host names in the Vagrantfile. The second thing I’d do would be to change the nginx config so that each hostname points to the correct subfolder under /vagrant/site1, /vagrant/site2 etc.
Or perhaps you were asking about running WordPress in multisite mode? In that case, yes, the tutorial in this blog post absolutely works just as well even if some of the future blog posts I’ll post on this subject might need some more testing before they work well with Multisite.
Did that answer your question or just make you more confused? Let me know.
Hey Erik,
I was talking more about being able to host different sites with the vagrant set up,so your approach of vagrant/site1/ vagrant/site2 would seem to work for me. Wouldn’t this approach be heavy on memory and speed though?
I have something similar setup for my Laravel sites, where I have a projects folder and in each in each one of these sites I have a laravel installation. In a folder i have Homestead setup and vagrant and I symlink what’s needed from the vagrant box in each site folder so it can run the laravel site from this setup: http://laravel.com/docs/5.1/homestead
I wonder if what I have setup here could work with wp too?