Easy WordPress local development environment

We believe it letting the build team work in the environment that works best for them – but a local dev environment should also be painless and quick to setup. So recently we’ve rolled out an optional setup using Laravel Valet+ to keep simple tasks simple.


As simple as Homebrew, Composer, and Valet+ are, using a basic bash script to set everything up saves time and effort for those who don’t want to build their own environment.

Combining Valet+’s ‘just works’ system with a simple script leveraging WP CLI for cloning sites lets anyone start working without quickly and without specialist knowledge.

Find the scripts and instructions over on Github (please make sure you review the code before running it!). Pull requests are welcome 🙂


The setup process isn’t very complicated, but there are probably ~10 steps. Since we’re in a fairly consistent environment (all recent Macs) it is easy to save users time by wrapping these up in an install script (install.sh). It makes a few presumptions, and has little error handling, as it is built for our use rather than a public product, but it has proven robust across Helpful.

Once it’s done, there is a folder called Sites in the users’ home directory. Any folder placed in there will immediately be available locally at http://foldername.test, and any emails sent will be caught by MailHog and viewable at http://mailhog.test. No messing with host files even, just create a folder. Easy.

Use / cloning sites

Having a local environment is only half the story. A remote site still needs to be cloned to be worked on. Currently the ‘easy’ solution is to create a new WordPress installation and import wp-content and the database. Again there aren’t too many steps, but it is a lot easier to wrap it in a script. Not only can we prompt users so they don’t forget anything, but some of the steps are prone to typos. For example, pulling down the database and performing the search-replace on the URL looks like:

ssh ${remote_server} "cd /var/www/${remote_site} && wp search-replace '${remote_site_url}' 'http://${local_site}.test' --all-tables --export --skip-plugins --skip-themes 2> /dev/null" | wp db import --skip-plugins --skip-themes - > /dev/null 2>&1

In one command this logs into the remote server over ssh, moves to the right directory, exports a copy of the database via the search-replace command to change the URL, and imports it into the local database.

The missing link

After running clone.sh, there is now a working local copy of a site. But there’s one part of our workflow that isn’t automated yet – linking to repositories. Themes and custom plugins are stored in git repositories and, currently, deployed with WPPusher. But working on your local clone of the repository, pushing, then pulling it to your local staging site with WPPusher is a very long route. So there is a final manual process:

  1. clone the relevant theme / plugin repository if needed
  2. delete the copy in the local staging site
  3. create a symlink from the repository to the right location in the local site, e.g. ln -s ~/Repositories/my_theme ~/Sites/foldername/wp-content/themes/

Wrap up

This will inherently be an evolving system. I’d really like to crack the final part – the difficulty is actually that we predominantly use Tower as a Git GUI. If we didn’t it would be possible to read the settings from WPPusher from the database and use that to clones directly into the local site.

Other than this, another feature on the roadmap is adding an option to skip cloning /wp-content/uploads, and using the Nginx config to direct requests for missing resources to the live URL. This would speed things up drastically when you are only making small changes as the database search-replace could also be replaced with just an update of the siteurl and home.

How do you manage your local staging environments? If you want to try this for yourself check out the repository and instructions. Just remember to read through the code first – it isn’t long – because there are key presumptions about locations of files. In fact, why not test it in a virtual machine (VM) – during development of this I discovered Parallels Lite is now available in the App Store and free for OS X VMs, then you can run the scripts risk free.