Learn how to create and register your own WordPress shortcodes to add dynamic content to your posts and pages.
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:
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:
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:
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.
You might like:
Learn the difference between implements and extends in TypeScript. Use Implements to implement interfaces and types, and extends to inherit from classes.
In this tutorial we will look at using YAML in PHP. Learn about Parsing and Writing YAML files using Symfony's YAML component.
Find bottlenecks, optimise and clean your code, and speed up your apps by measuring the execution time of your PHP scripts using microtime.
Learn how to regenerate and update WordPress media and image sizes both programmatically (without plugin), and also with a handy plugin.
Ever seen constants like __DIR__ and __FILE__ being used in PHP? These are 'Magic Constants', and this is how we can use them.