Development environments are essential in order to bring new software to life. Each technology has a specific set of tools that can be used to create such an environment, and so does web development. In the early days, we used web server solution stacks such as XAMPP or a virtual machine, where everything was installed manually. In the best case those virtual machines could be exported as a template. By applying custom scripts on these templates, the automatic installation of specific packages was possible. To make our lives easier, we used Vagrant for this, which made it comfortable to share the development environment for a specific project to all the developers involved. But it takes quite some time to create the scripts and also the runtime and the memory usage are limited (because this system is using VirtualBox). Also it is time-consuming to create multiple instances of the boxes and connect services between them. But there is a great solution to it: This is where Docker comes into play.
By using Docker the scripts for creating the environments are easier to read and maintain, and it gives you the possibility to work on docker images created by previous scripts (core images can be created and the docker files are lighter). The final piece in this puzzle is Docker Compose. This package allows the creation of a configuration file where all the commands that usually run in the console can be written in a more readable and expandable way. It also gives you the possibility to connect containers. This is how we can create components that are responsible for only one purpose: web server, database, emails and so on.
Using this power we can establish an easier workflow for WordPress projects, e.g. developing a plugin, a theme or even an entire new project based on WordPess. For this, we are going to use WPDC (WordPress Docker Compose): You can find it here in my GitHub directory.
Developing a full project
Here we have two scenarios. Either starting a fresh project or continuing from an existing source. The Docker Compose configuration from WPDC will cover both situations.
Starting a new project
When developing an entire project that is based on WordPress, the access to the entire wp-content directory is required, as this is the place where the work of a developer goes (themes, plugins, translations, etc.). The default configuration for the volumes (./wp-app:/var/www/html) will map all the files from the WordPress container, located inside the /var/www/html directory to the wp-app directory on the disk in the current working directory. This also means access to the core of WordPress and configuration files. This gives a huge advantage in performing updates manually and keeping them in a version control system, to assure that components are still working. There is also the option to directly map the wp-content directory (./wp-content:/var/www/html/wp-content). By using this approach, the WordPress core will not get into the version control system, but it’s risky to end up with a broken project if the theme or one of the plugins is not compatible with the new core of WordPress. This wont be an issue for an ongoing project, as it should rely on the latest core anyway, but if there is a longer pause on the project, trouble may occur. By having control over the core updates, code can be better managed and tested.
The docker-compose.yml file is using the official WordPress and MySQL images in the latest versions. It can be also reconfigured in order to use something that is closer to the actual server requirements of the project. The current wordpress:latest is using WordPress on PHP 5.6 with an Apache server, but by simply changing the tag latest with php7.0-apache it can use another docker image which provides PHP 7.0. The same applies for the database images. There is even an option to use the MariaDB images instead of MySQL when required.
After deciding with the team how the volumes should be configured and which images to use, it’s time to start the containers. Open a terminal and go to the directory of the docker-compose.yml file and run:
docker-compose up
This will create two new folders in the working directory. One where the WordPress app is located (wp-app) and one for the database (wp-data) which will be empty for now.
For convenience, it’s recommended to define a host name in the /etc/hosts, that will map to 127.0.0.1 (this is by default configured on the docker-compose.yml) instead of directly using the IP address in the browser. After this is done, the page can be opened in the browser to finish the WordPress installation.
From now on, the development environment is set and everybody can start configuring and coding the WordPress project.
From time to time, one of the team members should consider creating a set of test data in the database, which all developers may have access to. There is a small shell script called export.sh. Running this in the console will create a dump from the database container into the wp-data directory. This allows having a test SQL dump in the version control system.
In order to have the database in the same state as the dump, it’s enough to remove the containers and recreate them, by using:
docker-compose down docker-compose up
The wp-data directory will be used when creating the container for the database, and will load all the SQL files available in it (make sure to have only one dump file).
Continuing a project from an existing source
This case occurs when a full WordPress project (including the core) and a SQL dump are available. Create a wp-app directory and copy all the WordPress files into it. After that create another directory called wp-data (this is based on the default configuration) and place the database dump in it. Make sure to add proper image tags to the docker-compose.yml file when other PHP or MySQL versions are required. After doing so, the development environment can be started:
docker-compose up
Now a host entry is required (as described above) and WordPress has to use this new host. The easiest way to achieve this is by defining two constants in the wp-config.php file:
define('WP_HOME','http://wp-app.local'); define('WP_SITEURL','http://wp-app.local');
Developing a theme or plugin
By applying the same principle, it is possible developing only specific components for WordPress, like themes and plugins. All it needs is a proper configuration of Volumes in the docker-compose.yml file.
For theme development:
volumes: - ./theme-name/trunk/:/var/www/html/wp-content/themes/theme-name
For plugin development:
volumes: - ./plugin-name/trunk/:/var/www/html/wp-content/plugins/plugin-name
Creating or continuing the development of a theme or plugin works the same way as for a project.
Conclusion
It may require some time to install Docker, Docker Compose and to get used with the commands of Docker that bring the development environment to life. But it won’t take too long and the benefit is huge. This principle can be applied on all WordPress projects, and each team member can benefit from it, and save time for the development process. We are definitely saving a lot of time and unnecessary frustration!