Skip navigation
0

With Docker Compose, Xdebug, and PhpStorm, you can create a reproducible, isolated, and easily manageable local development environment that mirrors a production server, enhancing the quality of your WordPress projects.

Hello fellow WordPress Developers and advanced users! Today, I am excited to share a comprehensive yet straightforward tutorial on setting up a local WordPress development environment using Docker Compose. Having recently become part of the dynamic team at OnTheGoSystems, I decided to bring my comfort zone along with me, which is what this setup is all about.

The aim was simple: to develop a setup where I could have granular control over my development tools, integrating Xdebug and WP-CLI with the official WordPress Docker image. This setup isn’t about reinventing the wheel, but about customizing it to align with individual preferences and work styles. I am hopeful that this guide will be beneficial to you in configuring a similar environment, enhancing your journey in WordPress development.

Prerequisites

To get the most out of this tutorial, you’ll need to have the following dependencies installed:

  1. Docker: We will use Docker as our primary tool for creating, deploying, and running applications using containers. It allows us to package up an application with all parts it needs in a container, and ship it out as one package. What makes Docker even more powerful is its promise of granular control, allowing us to define every aspect of our application setup precisely. This control aids in crafting a development environment that suits our needs exactly.
  2. Xdebug Chrome Extension: This browser extension will help us step through our code, spot bugs, and improve the overall quality of our WordPress projects.
  3. PhpStorm: An intelligent and fully-featured IDE for PHP developed by JetBrains. It provides an editor for PHP, HTML, and JavaScript with on-the-fly code analysis and automated refactoring for these languages.

Why Docker, Xdebug, and PhpStorm?

Our objective is to establish a local WordPress development environment that is isolated, reproducible, and easily manageable. Docker forms the backbone of this setup, providing the infrastructure to contain and manage our application. Xdebug and PhpStorm are the complementary pieces of this puzzle, offering enhanced PHP code development and debugging capabilities.

Our journey will commence with crafting a Dockerfile that extends the official WordPress Docker image. We’ll enhance this image by incorporating Xdebug and WP-CLI, tools instrumental in our WordPress development and debugging tasks.

Next, we’ll draft a Docker Compose file to orchestrate two key services: WordPress and MySQL. And believe it or not, that’s essentially it! 

The beauty of this setup is that it results in a local development environment that not only mirrors a production server but is also easily replicable. This means that we can duplicate the exact setup across multiple environments or machines with ease, ensuring consistency and reducing setup-related issues.

Step-by-Step Tutorial

Step 1: The Dockerfile

Our journey begins with the creation of a new Dockerfile. This file instructs Docker on how to build our image. Here is the basic setup that I typically start with:

# Use the official WordPress image as a parent image
FROM wordpress:latest

# Install Xdebug
RUN pecl install xdebug 

# Install WP-CLI
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
    chmod +x wp-cli.phar && \
    mv wp-cli.phar /usr/local/bin/wp

# Copy xdebug.ini into the container
COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini

In this Dockerfile, we start from the official WordPress image. We then install Xdebug and WP-CLI separately for clarity and maintainability. The Xdebug configuration file (xdebug.ini) is copied into the appropriate directory in the container. This forms the basis of my go-to setup for a local WordPress development environment.

Step 2: The Xdebug Configuration File (xdebug.ini)

Now that we have Xdebug installed in our Docker image, we need to configure it to work in our local development environment. This involves creating an xdebug.ini file with the following settings:

ini
zend_extension=xdebug
xdebug.mode=debug
xdebug.client_port=9003
xdebug.start_with_request=yes

These settings enable the Xdebug extension, set it to start debugging with each request, and define the client port it should connect to (in this case, 9003). You may have noticed we haven’t specified a client_host yet, but fear not, it will come into play very soon in our setup process.

Step 3: The Docker Compose File

Next, we’ll create a docker-compose.yml file that sets up our WordPress and MySQL services:

yaml
version: '3'
services:
  # MySQL Service
  mysql:
    image: mysql:latest
    container_name: mysql_container
    restart: always
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
  
  # WordPress Service
  wordpress:
    depends_on: 
      - mysql
    image: wordpress:latest
    container_name: wp_container
    volumes:
      - ./wp_data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DEBUG: 1
      XDEBUG_CONFIG: client_host=host.docker.internal
    ports:
      - "8000:8000"

volumes:
  db_data:

In this file, we’ve defined two services — MySQL and WordPress. Both of these services have unique container names, for easier reference and management.

The restart: always directive ensures that the service will always restart if it stops unexpectedly. If it is manually stopped it is restarted only when the container is manually restarted.

The MySQL service mounts a Docker volume (db_data), ensuring persistent storage even if the container is deleted. For the WordPress service, we’re mounting a local directory (./wp_data) to the container. This means any changes in the WordPress files on our local system will be reflected in the container.

We’ve added two additional environment variables for the WordPress service — WORDPRESS_DEBUG to enable WordPress debugging and XDEBUG_CONFIG to specify the client host for Xdebug. The client_host is set to host.docker.internal, which is a special DNS name that routes to the host’s internal IP address, allowing Xdebug to communicate with our IDE on the host.

Please note that the client_host setting is tailored for Windows and macOS. For Linux, a common alternative is to replace host.docker.internal with the actual IP address of your machine, which can be obtained via the terminal command ip addr show.

Step 4: Running Your Local WordPress Development Environment

Once your Dockerfile, Xdebug configuration file, and Docker Compose file are ready, it’s time to bring your local WordPress development environment to life. 

To do this, simply navigate to the directory containing your Docker Compose file in the terminal, and run the following command:

bash
docker-compose up -d

This command will instruct Docker to start your services in the background.

Upon successful execution, you will have a WordPress site running on your local machine, accessible via http://localhost:8000. Any changes you make to your WordPress PHP files will now be reflected on this site, offering an easy and effective way to develop and debug your WordPress application.

Additionally, your MySQL service will also be up and running, accessible on port 3306. This provides a fully functional MySQL database for your WordPress application, replicating a true-to-life environment for your development needs.

Step 4.5: Bonus Step — Adding the phpinfo.php File

For those who want to delve a bit deeper into their PHP configuration, we can introduce a phpinfo.php file into our Docker image. When accessed, this file will present a comprehensive overview of your PHP settings.
To add the phpinfo.php file, you’ll first need to create it in the same directory as your Dockerfile. The file should contain the following PHP code:

<?php phpinfo(); ?>

Next, add the following line to your Dockerfile:

# Bonus: Copy phpinfo.php into the container
COPY phpinfo.php /var/www/html/phpinfo.php

This command will copy the phpinfo.php file into the WordPress root directory within the Docker image. 

To ensure these changes take effect, you’ll need to rebuild your Docker image and restart the Docker Compose services. Run the following commands in your terminal:

bash
docker-compose down
docker-compose up -d --build

The docker-compose down command stops and removes your current Docker containers. Following this, docker-compose up -d —build rebuilds the Docker image with the newly added phpinfo.php file, and restarts your WordPress and MySQL services in the background.
You can now access the phpinfo.php file by navigating to http://localhost:8000/phpinfo.php in your web browser. Here, you’ll see a detailed page outlining your PHP configuration, which can be a valuable resource for debugging and verification.

Step 5: Start Debugging

Now that you have your local WordPress development environment setup with Docker, Xdebug, and PhpStorm, you can start debugging your WordPress site. Here’s a quick rundown of how to get started:

  1. Set up Xdebug in PhpStorm: Open PhpStorm and go to File → Settings (Preferences on Mac) → Languages & Frameworks → PHP → Debug. Under the Xdebug section, ensure that the Debug port is set to 9003 and the Can accept external connections option is checked.
  2. Add a PhpStorm Server: Navigate to PHP → Servers. Add a new server with the name wordpress and the host localhost. Set the port to 8000. Ensure the path mappings are set correctly — the absolute path on the server for the wp_data folder should be /var/www/html.
  3. Install the Xdebug helper extension:  Install the Xdebug helper extension for Google Chrome. Once installed, click on the bug icon and set the IDE key to PHPSTORM.
  4. Start listening for PHP Debug connections: In PhpStorm, click on the bug icon in the top right corner to start listening for PHP Debug connections.
  5. Start Debugging: With the previous steps completed, you’re ready to start debugging your WordPress application. Just set your breakpoints in PhpStorm as needed, then simply reload your website. Happy debugging!

Conclusion

As we conclude this tutorial, I hope it becomes a valuable resource for you as it has been for me in my journey. The ability to customize this setup — like we did by adding the phpinfo.php file — opens a myriad of possibilities, making our development process more robust and efficient. All the code is available in this GitHub repository. Don’t hesitate to pull it, try it, and suggest improvements!

I personally use an Ubuntu OS, but the beauty of this setup is that thanks to Docker it does not matter! Thanks to the fact that Docker can run on any Operating System equally, whether you prefer macOS, Windows or Linux the setup and use is the same!

Thank you for accompanying me in this walkthrough. I hope to hear from you about your experiences or any suggestions you might have for further improving this setup. Remember, growth thrives on shared knowledge and the spirit of collaboration.

Happy coding, and let’s keep creating amazing WordPress experiences together!

How can we make WPML better for you?

Share your thoughts and comments about our plugin, documentation, or videos by booking a Zoom call with Agnes, our Client Advocate. Your feedback matters and helps us improve.

Book a call with Agnes