Contact!

WordPress development environment, Docker Compose

WordPress development environment, Docker Compose

This tutorial will show you how to set up a WordPress development environment (container) using Docker Compose. You will learn how to set up services for WordPress, MySQL and phpMyAdmin as well as the layout and structure of a docker-compose.yml file.

Note: If you are just here for a complete Docker Compose yaml file then you can skip to the end of the tutorial.

Download and install Docker

I’m going to assume that you’ve already downloaded and installed Docker, but if you haven’t you can go to the Docker website and follow the install instructions. This is your starting point, whether you are creating a development docker environment for WordPress, or any other tool.

Create a container environment for WordPress

We’ll start where all good projects start, by create a folder to house our development environment. To this folder add a file named docker-compose.yml.

Alternatively, we can do this via command line by navigating to the folder and running:

touch docker-compose.yml

We are going to be using the Docker Compose tool to make our lives as easy as possible. The docker-compose.yml file is the configuration file for Docker Compose.

Now add the version to the top of the file:

version: "3.8"

The version is going to specify which version of Docker Compose we want to use. We’ll be using the latest at the time of writing, but you may wish to check the current Docker Compose versioning yourself.

Networks, volumes and services

We will start by adding networks, volumes and services to our docker-compose.yml.

Open up your docker-compose.yml and add a network:

networks:
  wp-network:

The network isn’t actually necessary as it could be automatically created by docker. I like to add a network tag so that I can name my network; let’s call it semantics. A docker network basically just links all of our services together.

Now let’s add our volumes:

networks:
  wp-network:
volumes:
  wp-db:

Volumes are great because they allow us to persist data between our host and container. This data will be stored in the named directory and is editable regardless of whether the container is started up or powered down.

Finally, add the services:

networks:
  wp-network:
volumes:
  wp-db:

services:

The services are configurations for the actual ‘things’ we want to run. In this tutorial we will include the MySQL database, WordPress and phpMyAdmin as services.

Create a MySQL Docker service for the container

Next we are going to configure a MySQL service for our container. This will house our WordPress database.

With the MySQL service we are going to use the official MySQL image for Docker. An image is the template of instructions for building a Docker container, and using a pre-configured image means that we don’t have to create one ourselves.

  services:
    mysql:
        image: mysql
        volumes:
          - wp-db:/var/lib/mysql
        ports:
          - 8081:3306
        environment:
          MYSQL_DATABASE: gavsblog
          MYSQL_USER: gav
          MYSQL_PASSWORD: blog
          MYSQL_ROOT_PASSWORD: root
        networks:
          - wp-network

Now let’s have a look at what we did:

After specifying an image we link a volume. In this instance we are making the content of ‘/var/lib/mysql’ available across all of our services under ‘wp-db’.

Next we add the port we want the service to run on.

Then we are specifying the environment variables needed to create and run the service.

Finally we hook the service up to our ‘wp-network’.

Create a WordPress Docker service for the container

Now we can add our WordPress service. Luckily for us there is an official WordPress image for Docker, so we’re just going to use that.

  wordpress:
    depends_on:
      - mysql
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: gav
      WORDPRESS_DB_PASSWORD: blog
      WORDPRESS_DB_NAME: gavsblog
    networks:
      - wp-network

The setup follows a similar pattern to the MySQL, except this time we specify ‘depends_on’. We use ‘depends_on’ to make sure that dependencies start in the correct order. In this case, the WordPress service can’t start until the MySQL service is available (we need a database to run WordPress).

If we were to build our container at this stage then everything should work. You can follow the WordPress installation and have a working site. There are still a few more steps to make this a good development environment, though.

Expose your WordPress files using a volume

The problem is that we are developers, so we want to play with the code. To do this we are going to mount a volume to make the WordPress files accessible.

    volumes:
      - ./wordpress:/var/www/html
  wordpress:
    depends_on:
      - mysql
    image: wordpress
    volumes:
      - ./wordpress:/var/www/html
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: gav
      WORDPRESS_DB_PASSWORD: blog
      WORDPRESS_DB_NAME: gavsblog
    networks:
      - wp-network

This volume will create a file in the project root directory called ‘wordpress’. Once the container has been built, all of our WordPress files will be located here. Remember that volumes persist data, so once this is built we will always be able to access the files.

Create a phpMyAdmin Docker service for the container

Most WordPress users will want a tool to manage their database. I’ve always used phpMyAdmin, which is an administrative tool for MySQL. This step is completely optional, so feel free not to use it.

Similarly to the other services, we are lucky enough to have an official docker image available for phpMyAdmin. Like the others, we are going to just use this.

Add configuration for phpMyAdmin to your list of services:

  phpmyadmin:
    depends_on:
      - mysql
    image: phpmyadmin/phpmyadmin
    ports:
      - 8082:80
    environment:
      PMA_HOST: mysql
      MYSQL_USER: gav
      MYSQL_PASSWORD: blog
      MYSQL_ROOT_PASSWORD: root
    networks:
      - wp-network

This stuff should be getting more familiar to read now. The phpMyAdmin service depends on the MySQL service, is built from the phpMyAdmin official image and uses port 8082:80 on our wp-network.

The image requires 4 environment variables, with PMA_HOST (the database host) pointed at the MySQL service we created earlier.

A complete Docker compose yaml file for WordPress development

When you put all of the above steps together you should have a file which looks like the following:

version: "3.8"

networks:
  wp-network:
volumes:
  wp-db:

services:
  mysql:
    image: mysql
    volumes:
      - wp-db:/var/lib/mysql
    ports:
      - 8081:3306
    environment:
      MYSQL_DATABASE: gavsblog
      MYSQL_USER: gav
      MYSQL_PASSWORD: blog
      MYSQL_ROOT_PASSWORD: root
    networks:
      - wp-network 
  
  wordpress:
    depends_on:
      - mysql
    image: wordpress
    volumes:
      - ./wordpress:/var/www/html
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: gav
      WORDPRESS_DB_PASSWORD: blog
      WORDPRESS_DB_NAME: gavsblog
    networks:
      - wp-network

  phpmyadmin:
    depends_on:
      - mysql
    image: phpmyadmin/phpmyadmin
    ports:
      - 8082:80
    environment:
      PMA_HOST: mysql
      MYSQL_USER: gav
      MYSQL_PASSWORD: blog
      MYSQL_ROOT_PASSWORD: root
    networks:
      - wp-network

Running Docker Compose via command line

Now all we need to do is run the file using Docker Compose.

Navigate to your development folder via command line/command prompt and run the following:

docker-compose up -d

Let the process complete (and allow a few minutes after for the containers to finish building) and you’ll have your working development environment running on http://localhost:8080.

If you have included phpMyAdmin then you will be able to access the application via http://localhost:8082. To log in you can either use the username ‘root’ and password ‘root’ or the MySQL user and MySQL password that you’ve configured in the docker-compose.yml file.

  1. Benny says:

    Awesome! Thank you, I was struggling with docker and WordPress… this really helped.

Join the discussion!

You might like:

Create, register and use shortcodes in WordPress

Create, register and use shortcodes in WordPress

by Gav 18/03/2023

Learn how to create and register your own WordPress shortcodes to add dynamic content to your posts and pages.

How to use guard clauses in JavaScript

How to/why use guard clauses in JavaScript

by Gav 16/03/2023

Learn how to improve code readability and performance by using guard clauses in JavaScript. Discover their benefits and best practices.

Implements and Extends, Object Oriented TypeScript

Implements and Extends, Object Oriented TypeScript

by Gav 15/03/2023

Learn the difference between implements and extends in TypeScript. Use Implements to implement interfaces and types, and extends to inherit from classes.

Reading/Parsing and Writing YAML files in PHP, Symfony

Reading/Parsing and Writing YAML files, PHP Symfony

by Gav 14/03/2023

In this tutorial we will look at using YAML in PHP. Learn about Parsing and Writing YAML files using Symfony's YAML component.

Measuring code execution performance in JavaScript

Measuring code execution performance in JavaScript

by Gav 13/03/2023

Measuring code execution performance is an important way to identify bottlenecks. Use these methods in JavaScript to help optimise your code.

Measuring script/code execution time in PHP using microtime

Measuring script/code execution time in PHP, microtime

by Gav 06/03/2023

Find bottlenecks, optimise and clean your code, and speed up your apps by measuring the execution time of your PHP scripts using microtime.

Regenerate WordPress media image sizes, programmatically

Regenerate WordPress media image sizes, programmatically

by Gav 25/02/2021

Learn how to regenerate and update WordPress media and image sizes both programmatically (without plugin), and also with a handy plugin.

Magic Constants in PHP. What they are and how to use them.

Magic Constants in PHP. What they are and how to use them

by Gav 15/02/2021

Ever seen constants like __DIR__ and __FILE__ being used in PHP? These are 'Magic Constants', and this is how we can use them.

Detecting Keypress JavaScript

Detect single and multiple keypress events: JavaScript

by Gav 16/10/2019

Learn how to use event listeners to detect and handle single and multiple keypress events in JavaScript. Add modifier keys to your application!