How to use Docker for WordPress development

This article is a simple tutorial on how to start using Docker for WordPress development.

In the last couple of months, I had a problem with the XAMPP MySQL database. Without any particular reason, from one day to another, it just failed. XAMPP UI does not show any error.

DB recovery does not help, and it seems that every StackOverflow solution does not work. And digging deeper into the database stack did not bring any working solution.

The only solution which seems to work is to delete the XAMPP entirely and create a fresh new installation. Of course, this is a very tedious and time-consuming solution.

Moreover new MacOS update Catalina just made things worse, and XAMPP MySQL failed instantly. Instead of starting using MAMP, which is just the same way of doing things as XAMPP, I have decided it is the right time to start utilizing the power of Docker for WordPress development.

Using Docker for WordPress development

I have decided to create this simple tutorial for WordPress development with Docker for whoever would like to need it. This tutorial is written for macOS/Unix systems based operating systems. However, it is helpful for Windows users as well.

Here is a simple list of steps necessary for starting WordPress development with Docker:

Step no. 1 – Install Docker

Well, of course, the first step is to install Docker itself. I will step over this step while this could be a stand-alone tutorial for that. However, it is super easy, and it can complete even beginner PC user alone.

Step no. 2 – Think what do you need for WordPress development

We will need three containers for WordPress development with Docker. These containers will be:

  • PHP server running WordPress
  • MySQL or MariaDB database based on your choice
  • Access to database (over phpMyAdmin GUI)

Accessing the database over GUI is optional. Same as selecting the database of your choice. MySQL or MariaDB is up to your preference. So based on what are your needs, you should check the appropriate section in the next step.

Step no. 2 – Create docker-compose.yml file

Create a new directory for a project you want to develop. It will be the location of your choice. This folder should contain single file docker-compose.yml.

TIP: There is a nice hack for doing all the steps in one. Just type in your terminal this command mkdir NEW_PROJECT_NAME && cd $_ && touch docker-compose.yml and you will all do this in one line.

Copy code below to docker-compose.yml

version: "3.1"

networks:
  wp:

volumes:
  db_storage:

services:

  wordpress:
    container_name: CUSTOM_PROJECT_NAME_wordpress
    image: wordpress
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
        - ./:/var/www/html/wp-content
    ports:
      - 80:80
      - 443:443
    networks:
      - wp
    depends_on:
      - db

  db:
    container_name: CUSTOM_PROJECT_NAME_db
    image: mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    volumes:
      - db_storage:/var/lib/mysql
    ports:
      - 3306:3306
    networks:
      - wp

  phpmyadmin:
    container_name: CUSTOM_PROJECT_NAME_db_gui
    image: phpmyadmin
    restart: always
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 8080:80
    networks:
      - wp
    depends_on:
      - db

Let’s cut down the composer file to pieces and figure out what it does.

version: "3.1"

networks:
  wp:

volumes:
  db_storage:

services:
Line Description
version: “3.1” Version of the Compose file format. Version 3 or higher is the most current and recommended to use.
networks: wp: All networks used for the service. We need to create just one custom network for our containers.
volumes: db_storage: All volumes used for the service. We need to create just one custom volume for our containers.
services: All containers used for this service. We need to create just one custom service.
wordpress:
    container_name: CUSTOM_PROJECT_NAME_wordpress
    image: wordpress
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./:/var/www/html/wp-content
    ports:
      - 80:80
      - 443:443
    networks:
      - wp
    depends_on:
      - db
Line Description
container_name Define the container name in CUSTOM_PROJECT_NAME_wordpress.
image: wordpress If you do not define nothing, latest version of Docker file will be downloaded. To specify custom version of WordPress just add double dot e.g.: wordpress:5.3.0
restart: always Define restart policy – Docker reference
volumes:
– ./:/var/www/html/wp-content
Local folder mapped to container wp-content path. For normal theme or plugin development we do not need to access WordPress core file. Docker WordPress image
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WordPress Docker environment. If you use containers just locally, I would suggest to keep this dummy passwords. Otherwise you are free to change it to your needs. Docker environment
ports:
– 80:80
– 443:443
I/O ports for HTTP and HTTPS
networks:
– wp
Network to join.
depends_on:
– db
Dependency declaration.

With just a simple change of DB image from MariaDB to MySQL, you can get different database engine according to your needs. Otherwise, everything is the same for both containers.

db:
    container_name: CUSTOM_PROJECT_NAME_db
    image: mariadb
    # image: mysql
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: wordpress
        MYSQL_USER: wordpress
        MYSQL_PASSWORD: wordpress
    volumes:
        - db_storage:/var/lib/mysql
    ports:
        - 3306:3306
    networks:
        - wp
Line Description
container_name Define the container name in CUSTOM_PROJECT_NAME_wordpress.
image: mariadb If you do not define nothing, latest version of Docker file will be downloaded. Docker MariaDB image
If you want to MySQL database instead of MariaDB, type just image: mysql and latest image of MySQL will be downloaded.
restart: always Define restart policy – Docker reference
volumes:
– db_storage:/var/lib/mysql
Name volume allow data persistence without bothering where the data are stored.
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
WordPress Docker environment. If you use containers just locally, I would suggest to keep this dummy passwords. Otherwise you are free to change it to your needs. Docker environment
ports:
– 3306:3306
Database access ports.
networks:
– wp
Network to join.
phpmyadmin:
  container_name: CUSTOM_PROJECT_NAME_db_gui
  image: phpmyadmin
  restart: always
  environment:
    PMA_HOST: db
    MYSQL_ROOT_PASSWORD: password
  ports:
    - 8080:80
  networks:
    - wp
  depends_on:
    - db
Line Description
container_name Define the container name in CUSTOM_PROJECT_NAME_wordpress.
image: phpmyadmin/phpmyadmin If you do not define nothing, latest version of Docker file will be downloaded.
restart: always Define restart policy – Docker reference
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: password
WordPress Docker environment. If you use containers just locally, I would suggest to keep this dummy passwords. Otherwise you are free to change it to your needs. Docker environment
ports:
– 8080:80
Connect local 8080 port call to 80 port at Docker service.
networks:
– wp
Network to join.
depends_on:
– db
Dependency declaration.

Step no. 3 – Run Docker with docker-compose up -d

From now on all will go quickly. Just type docker-compose up -d and after initial download of all dependencies everything goes smoothly. When all your containers will shine as done you are ready to proceed.

If you run docker ps, you should now see three services with the name you defined in the docker-compose.yml file.

Step no. 4 – Install WordPress

You can find the new WordPress installation at http://localhost:8080/ address. Just proceed with the installation as usual and create a new WordPress installation in your local directory. From now on, you can access this WordPress installation as usual.

If you want to access database with phpMyAdmin use http://localhost:8080/index.php address. If you do not change password in yaml file, use name:password and password:password as login information.

So remember, to access:

  • http://localhost:80/ – WordPress
  • http://localhost:8080/ – phpMyAdmin (name: password, password: password)

Step no. 5 – Load your Git theme/plugin repository

Everything works as if you would be developing any other WordPress project now. If you have your project versioned in Git, go to themes or plugin folder and Git clone your project there. Any change made there will reflect as git diff in Git.

Step no. 6 – Shutdown the Docker processes when you finished

Finally, to proceed and stop Docker container lifecycle, you need to learn a few more commands. They are:

  • docker-compose up – run the processes, however they are attached to life of your terminal window. Docker process will be terminated on the terminal window close up.
  • docker-compose up -d – leaves the processes running without being attached to your terminal window. Use -d as “detach” for Docker to starts the containers in the background and leaving them running, independently on your terminal window life. Docker reference for up
  • docker-compose stop – stop the processes
  • docker-compose down – stop and removes the processes
  • docker-compose rm -v – docker cleanup
  • CTRL+C – killing processes, terminal key shortcut

I recommend you kill the Docker processes for your theme every time you think you finished the day. It is advice based on experience from life. If you kill the processes the next day, you can be sure they are not working because they are down, but not because something else went wrong. Plus, if you switch often projects as I do, it is good to keep the system utilization low and order everything.

Known issues

While dealing with Docker, some things can go wrong. However, we will not go through all of them here. Let’s take a look only at the most occurring issues.

Error establishing a database connection

Error establishing a database connection - WordPress

If you get an error saying Error establishing a database connection check the name interconnecting database credentials and database name between WordPress and database.

Conclusion

I hope you liked this simple tutorial explaining how to quickly and effectively set up Docker for WordPress development. If you have any comments or constructive criticism or have other ideas on enhancing this YML file or tutorial, please write me a comment. I will appreciate it.

This entry was posted in Tutorials and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.