WordPress Development with Docker

Web developers eventually come across WordPress. Some stumble upon it as they take their first steps in web development, for others it’s the staff of life. Instead of starting WordPress projects by downloading the latest version and firing up your local LAMP/MAMP/XAMPP/etc services, you could just try Docker – and exactly that’s what we are going to show you in this blog post.

As a developer you have probably already heard of Docker. Docker is everywhere and the container software’s popularity is still on the rise.

Google Search Trend for “docker”

In case you haven’t heard of it: Docker is a software for ‘containerization’ (virtualization of containers). It’s called container because you package all kind if programs or services into different packets (= container) – most likely separated by task. This containerization should increase performance and portability, compared to normal virtual machines. If you want to know more about it, check out the Docker website www.docker.com.

So what about applying this concept to the development of WordPress plugins or themes? Well, first let’s think about what we actually need to dive into WordPress (development):

  1. WordPress
  2. Webserver with PHP
  3. Database (e.g. MySQL)
  4. Optional: phpMyAdmin

We have to package these services into Docker containers. Such containers can be created easily, thanks to central repositories like Docker Hub. With a few lines of configuration we can use already existing images from software developers and the community in minutes.

The configuration itself takes place in the file docker-compose.yml. This file serves the definition of our services and uses YAML .

 

Database

For our case we choose the latest version of MySQL as our database system. We set a root-password and a location (local folder db_data/) to save our data, so we have access from our local filesystem.

  mysql:
    image: mysql
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password

 

WordPress

We settle for the official WordPress image as our base, which comes with the latest version of WordPress as well as a configured web server with PHP 7.2. The container’s port 80 is mapped to our local port 8080.
To enable the connection to our database, we hand over the database’s root-password.

Let’s assume we are developing a plugin for WordPress. This plugin lets us upload tournament results of a game. The results are processed, saved into our database and finally generate up-to-date standings.

We start by writing the source code in our local development environment (use whichever editor or IDE you like) and now we want to use this plugin code in our Docker container.
We do this by setting up volumes in the configuration. As previously used in the database section, we provide a local path and map it to a path in the container, which then get linked.
My local path ./wp-content/plugins/mtg_league_tracker in the current directory then links to /var/www/html/wp-content/plugins/mtg_league_tracker in the container. We do the same for the wp-uploads/-folder.

  wordpress:
    depends_on:
      - mysql
    image: wordpress:php7.2
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: password
    volumes:
      - ./wp-content/plugins/mtg_league_tracker:/var/www/html/wp-content/plugins/mtg_league_tracker
      - ./wp-content/wp-uploads:/var/www/html/wp-content/wp-uploads

 

phpMyAdmin

For easier maintenance of our database development (saving & reading data) we add a service for phpMyAdmin. We use the previously defined database password and map the local port 8081 to the container’s port 80.

Additionally we use links to tell the service to use the MySQL service we’ve already added.

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 8081:80
    links:
      - mysql:db

 

Let’s put the pieces together…

The complete docker-compose.yml file looks like this:

version: '3'

services: 
  mysql:
    image: mysql
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 8081:80
    links:
      - mysql:db
  wordpress:
    depends_on:
      - mysql
    image: wordpress:php7.2
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: password
    volumes:
      - ./wp-content/plugins/mtg_league_tracker:/var/www/html/wp-content/plugins/mtg_league_tracker
      - ./wp-content/wp-uploads:/var/www/html/wp-content/wp-uploads

You can start all your containers by simply entering the following into your favourite command line:
docker-compose up -d

After a brief loading period, you can access your WordPress page via a web browser under http://localhost:8080. phpMyAdmin is accessible under http://localhost:8081 .

To stop the containers, just type in docker-compose stop . Thankfully, your database doesn’t get wiped and you don’t have to setup WordPress every time you fire up your containers again.
If you need a debug output (e.g. web server), you can use docker-compose logs -f. Alternatively, you can omit the -d option when starting your containers.

After firing up the containers for the first time, we have to setup WordPress

 

Happy Development

If everything went smoothly, we can continue the development via our local filesystem and don’t have to deal with web servers and so on.

The directory structure for our example plugin looks like this:

wp_mtg_league/
  -> db_data/
  -> wp-content/
    -> plugins/
      -> mtg_league_tracker/
        -> mtg_league_tracker.php
  -> wp-uploads/
  -> docker-compose.yml

 

Our plugin (MTG League Tracker) was correctly loaded from our local directory

Docker has the ability to simplify our development process. No tedious configuration of development environments on different workplaces anymore. Just fire up your container and you are good to go.

References:

https://developer.wordpress.org/plugins/the-basics/
https://docs.docker.com/compose/wordpress/