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.
To get the most out of this tutorial, you’ll need to have the following dependencies installed:
- 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.
- Xdebug Chrome Extension: This browser extension will help us step through our code, spot bugs, and improve the overall quality of our WordPress projects.
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 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:
- 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.
- 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.
- 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.
- 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.
- 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!
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!