Three ways to set up a WordPress local development environment


Local development environments are important to have as a web developer and WordPress is no exception. I have used Local by flywheel for many years now because it is extremely easy to get started and has a really nice user interface. You install the program, click a few buttons and an environment is set up.

But it does have a few problems:

  • It can be hard and time consuming to set up in a team environment as it requires everyone to set it up and configure.
  • It’s pretty slow sometimes

Wanting better processes for the team, I wanted to set up something where it’s as easy as clone a repo and running a few commands. This led me to explore a few other options and I wanted to share that in this post.

I ended up trying three options, all Docker related but handled in different ways. wp-env, plain Docker and Lando.

The documentation for each of these are quite good, so I won’t be going into too much detail of how to set this all up, you can go to the offical docs for that. This post will be more around my personal experience and opinions about each option I tried.

wp-env

The first one I tried was wp-env, the officially supported WordPress dev environment that uses Docker under the hood. I like to stay as close to WordPress as possible so I thought it’d be good to try. The docs are really good so I would recommend you go there to get started.

Essentially all you have to do is install Docker, then npm install @wordpress/env. From there you can run wp-env start in any directory and it will start a WordPress environment pointing to that directory. You also get Composer, PHPUnit, and wp-cli included as well.

My favourite thing about wp-env was the ability to use a .wp-env.json file to configure the environment. As a test I wanted to see if I was able to set up my personal site locally.

After a couple of hours going the docs, here’s what my .wp-env.json file looked like.

{
    "plugins": [
        "<https://downloads.wordpress.org/plugin/query-monitor.3.15.0.zip>",
        "<https://downloads.wordpress.org/plugin/custom-post-type-ui.1.16.0.zip>",
        "./plugins/wp-migrate-db-pro",
        "./plugins/gravityforms",
        "./plugins/gravityformsconvertkit"
    ],
    "themes": [ "./themes/ptdevblocks" ],
    "mappings": {
        "wp-content/plugins" : "./plugins"
    }
}

In my root directory I had two folders alongside the .wp-env.json file, a plugins folder and a themes folder.

I used the ‘plugins‘ and ‘theme‘ keys to tell wp-env what themes and plugins to install.

The ‘mappings‘ key maps the plugins folder in the environment with the plugins folder on my local PC. This works a bit like volumes in Docker.

With this setup I was able to spin up a local environment and pull down the uploads and database of my website in two commands.

# Start the environment
wp-env start

# Use WP Migrate to pull the DB and uploads
wp-env run cli wp migrate pull https://paultruong.dev <site-secret> --media=all

This worked pretty well but I wanted to see if I could reduce it down to one command, I also wanted to add extra services to the environment like Mailhog and Redis. I couldn’t find a way to do this with wp-env so I thought I’d try my hand with standard Docker.

Docker Compose

Since wp-env was using Docker I thought I could try using Docker myself to create a more customised dev environment. After spending a few hours on Docker I was fully confident that I could use Docker to set up the environment exactly how I want it via Docker Compose.

If I got over the learning curve.

Turns out Docker is very complicated and the best I could do was change the example docker-compose.yml file.

services:
  db:
    # We use a mariadb image which supports both amd64 & arm64 architecture
    image: mariadb:10.6.4-focal
    # If you really want to use MySQL, uncomment the following line
    #image: mysql:8.0.27
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=somewordpress
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
    expose:
      - 3306
      - 33060
  wordpress:
    image: wordpress:latest
    volumes:
      - ./wp-content:/var/www/html/wp-content
      - wp_data:/var/www/html
    ports:
      - 80:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
volumes:
  db_data:
  wp_data:

After this I tried to add wp-cli as well but couldn’t get it working. So I moved on to another tool recently discovered. Lando.

Lando

I found out about Lando from a coding interview I did for a dev role at an agency. They sent me a test and it used Lando to spin the environment.

Lando is an abstraction layer on top of Docker. Like Docker it uses a YAML configuration file as well. This time in the form of a .lando.yml file.

The thing that makes Lando really nice is that it has a bunch of pre configured services and recipes you can easily add to your configuration. The most basic WordPress .lando.yml file looks like this.

name: lando-wp-test
recipe: wordpress
config:
  webroot: .

Once that’s setup you can run lando start and Lando does all of the heavy to set up your environment. Well almost…

Lando doesn’t actually install WordPress for you, it just sets up the environment (containers, services, database etc.) to work with it. You still need to install it yourself. Luckily the WordPress recipe has wp-cli preinstalled so you can run lando wp core download after starting the server. WordPress will then be downloaded and you’re on your way.

I did see that it has support for build steps and events, which means it’s very much possible to automate this and more. Between going through the Lando docs and pulling apart the agencies .lando.yml file, I am quite optimistic about Lando.

So whats the conclusion?

For me personally, I am quite optimistic about Lando, it has a good balance of ease and flexibility.

wp-env was super easy but was a little too bare bones, although I think it’ll be good for single plugin projects with how convenient it is to spin up. A straight Docker setup is just too complicated for me right now and I don’t have the time to dig deep into it, maybe in the future.

As an aside, I still think Local by Flywheel is still an excellent option for solo developers if you just want to quickly spin up an environment to work in without worrying about working in the command line and configuration files. It just gets harder to use as you scale up a team.

For now though I will be sticking with Lando and wil be using it to build a new starter template for WordPress developement. Once that’s done, I’ll be sure to blog about that too.

Need a web developer? Let’s chat