Technouz

The Ultimate WordPress Website Development Workflow

By Zahid Mahmood / 27 August 2017

Whenever I browse the 'Web Development' or 'WordPress' areas of Twitter and Reddit, I always come across intriguing questions and opinions on WordPress development workflows. Strangely, I find that a number of developers don't feel they have found the best workflow which allows for their needs of agility, flexibility and ad-hoc development wherever and however its needed. So, for anyone interested, I have documented the workflow I use below…

Considerations to note:

  • I am not claiming my workflow is perfect, but it works perfectly for me
  • It's designed for full-site WordPress development - I rarely ever just design a theme or plugin, and there are better options available for this (see Sage)
  • There's a strong focus on continuous integration, modularity and source control integration
  • I haven't yet added much automation, including testing. Deployment, updates, source control are very much handled manually but this suits my needs

The initial configuration

I usually start by creating a GitHub repository for my project. You can name it whatever your like, but I find that adding a suffix of '-wp' makes it easy to distinguish between WordPress projects and normal web projects.

With the repo set up, I use VagrantPress to install a WordPress instance on my local machine. I usually clone the VagrantPress repository in to a new folder in the Downloads folder on my Mac as follows:

cd Downloads git clone https://github.com/vagrantpress/vagrantpress exampleproject

This creates a folder called 'exampleproject' in Downloads in which I will do all of my development. Next I start the instance by navigating to the directory using the command line as so:

cd exampleproject vagrant up

If this is your first time using Vagrant you'll need to install and configure the dependencies listed on the GitHub page for the project. This includes VirtualBox which is a free virtualization software in which a Linux instance will be installed, and your WordPress installation hosted. Getting started with Vagrant is very easy so taking five minutes to configure everything is well worth it.

Typically, running the vagrant up command can take up to two minutes for your instance to be ready to start developing. For longer stretches of development this is fine, but periodic, quick bug fixes become tedious. If it's your first time running Vagrant it could a take longer as it needs to download a Linux image file to run the virtual machine (this only needs to be done once).

I chose Vagrant over Docker because it allows me to develop in isolated environments. In hindsight, seeing Docker become so successful and compatible with many third-party services and hosts I may consider migrating at some point in the future. One of the clear benefits I see with Docker today is it's adoption by Parallels Plesk. Using Docker would make automated deployments (and backups) so much easier, faster and robust. Still, using GitHub to deploy hasn't given me any grief thus far so there isn't an incentive for me to migrate over.

Once you've got your Vagrant instance running, you should be able to preview the default WordPress installation by visiting vagrantpress.dev from your browser. You can easily change this address through the Vagrant configuration files and run multiple development environments simultaneously.

My next step is to create my initial source control commit. To do this I head back over to the Terminal command line and navigate to the WordPress wp-content directory as below:

cd wordpress/wp-content

Then, I clean up the wp-content directory by removing any default plugins and themes. This step is totally optional and just depends on what you are trying to achieve with your development. I usually delete the default plugins in the wp-contemt/plugins/ directory and all but the default theme in the wp-content/themes directory.

Next I initialise my Git repository and add my GitHub repository as a source. The final step here is to push the initial commit:

git init git add . git commit -m "initial commit" git remote add origin https://github.com/username/exampleproject.git git push -u origin master

Now I have full source-code integration of all files within wp-content. For those not familiar with the significance of this: it means that any user-customised data is now backed-up with source control. User uploads, themes and plugins are all stored within the wp-content folder which is now being backed up to GitHub on demand. This also means any changes to a plugin or theme is also backed up, and reverting back to a state prior to an update is also possible.

Not only is this great for deployments, it's really smooth for backups and server migrations too!

Deploying the contents of wp-content to any WordPress environment will be as simple as a git clone command - more details later.

Main development branch

I like to create my branches early on because I focus my environments around them.

Again, this step is flexible and depends on what you are trying to achieve. I prefer to keep it simple and create a branch called main-dev which represents any general development work, and then I create singular branches from my main branch for feature-based development work.

The master branch remains as the most up-to-date version of Live code.

Once I have created my main-dev branch, I checkout my local development environment (Vagrant) to the main-dev branch using the following command-line execution:

git checkout main-dev

Staging and live environment

The next step I take is to set up a staging and live environment. You can wait until the first release of your website is finished before you create a live environment. Again, this really depends on your projet and requirements. For this example, I will walk through setting up the live environment, but the staging environment is the same concept.

We start by installing WordPress on the server. This can be done using a tool available through our Control Panel, manually, or any other installation/deployment method. Then, launch the Terminal command prompt and SSH in to your server. Next, go in to the directory which contains your fresh WordPress installation, and replace the existing wp-content folder with the GitHub repository like so:

cd wp-content rm -rf wp-content git clone https://github.com/username/exampleproject wp-content cd wp-content

This code simply removes the wp-content directory, and replaces it with the one we pushed to source control from our local (Vagrant) development environment. Now, the files on our Live website are also integrated with source control!

For the live server, the master branch will suffice, so we do not need to checkout to any other branches. For a staging environment I would typically checkout to the main-dev branch like this:

git checkout main-dev

In essence, the master branch represents your live code and should contain the latest release. This is to be kept up to sync with the Live environment. Any changes (via pull requests or hotfixes) to the master branch can be synced with the Live environment by running the command: git pull. Similarly, any file uploads can be synced to the master by creating a commit and then pushing it to GitHub.

The staging environment should be your latest version of (stable) development code. I use the staging environment to show clients iterative work before going live, or testing major WordPress version, theme or plugin updates. The beautify with git source control integration is that we can switch our codebase to feature-branch by simply running the command git checkout feature-branch. All of this can be done without interfering with the live code, and will only be pulled and merged once tested, approved and ready. I typically leave the staging environment checked-out to main-dev and use pull requests from feature branches before pulling the changes in to the staging environment. But this post isn't about the best source-control practises, and every decision you make should suit your project requirements.

Database syncronization

Nearly there! The files and folders within the wp-content directory do not contain all the user data for our WordPress websites. Currently, we have two (or three) completely separate WordPress instances installed, all showing different content.

The next stage is to find a system to sync these databases. For my use, I only ever need to pull data from my live database to my development databases. I rarely need to pull data from my development databases to my staging database, however the method I am going to detail does support both cases.

To achieve my database synchronization, I use an open-source plugin called WP-Sync-DB.

I install the plugin on all environments (and branches) of the website. Then after activating the plugin on all the instances, I use the 'pull' feature to import the Live database to my Vagrant and staging environments. I save the profile as live-to-dev and live-to-staging respectively. Very rarely, when I need to, I can use the 'push' feature to push from my development environment to my live instance since I don't develop on a static and publicly available IP address.

What's great about this plugin is that it automatically does a search and replace on the database migration. Once you have set up the plugin the first time, it only takes one click and thirty seconds to synchronise your database. I love the simplicity and reliability of the plugin so much that it's my go-to and at the core of my continuous-integration (CI) development life-cycle.

Developing on the go

Sometimes I don't want to go through the effort of setting up a Vagrant instance for a smaller project. Or, maybe I'm using a borrowed/public machine. In that case, I like to have a readily accessible development instance that I can access from anywhere. Cue Cloud9 IDE. An online IDE environment that has WordPress support out of the box, as well as generous offerings for my other projects including LAMP, Node, Ruby and more! I follow the same procedure on Cloud9 as I do on my other development environments: install WordPress and the replace the wp-content folder with the GitHub repo. Again, this instance can harness the use of WP-Sync-DB to keep the database synchronised.

Cloud9 is one of many online IDEs, but I chose to put this one in my workflow because:

  • the IDE is powerful, with plentiful of features including a debugger, multiple terminal instancesm, syntax highlighting and code collaboration
  • Free license is more than sufficient. Paid licenses do not break the bank and are fantastic value for money
  • Cloud9 was bought by Amazon in the summer of 2016 - that tells me it's well-funded and likely to stick around
  • Can take up to five minutes to load up projects that have been stale for a while, but currently the free plan offers unlimited projects
  • The software is open-source. You can download the Docker containers and IDE from GitHub and host it on your own server, totally independent of Cloud9

I find Cloud9 so overwhelmingly useful, that for many of my projects I just don't bother with a local Vagrant instance anymore. That being said, it does need an internet connect and runs best on Google Chrome which is a massive power-hog… Not the most ideal for developing on the go when battery life may be a concern.

My workflow synopsis

  • Use GitHub source control for CI and deployment of wp-content directory
  • Use WP-Sync-DB to copy and sync databases
  • One branch per environment
  • Staging environment is publicly accessible and can be used to show client work in progress for feedback. Simply checkout to the development branch and pull changes via SSH/Terminal

Feel free to tweet any suggestions to @technouzcom.

Thanks for reading!

My name is Zahid Mahmood, and I'm one of the founders of Anterior. I started this technology blog when I was in high school and grew it to over 100,000 readers before becoming occupied with other projects. I've recently started writing again and will be posting more frequently.