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 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:
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
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.
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
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.
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.
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:
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.
checkoutto the development branch and
pullchanges via SSH/Terminal
Feel free to tweet any suggestions to @technouzcom.