Subscribe to PHP Freaks RSS

Developing WordPress sites with Docker

syndicated from planet-php.net on August 1, 2019

I recently set up a new WordPress based website and local Docker-based development environment. This post documents what I did, so that I can do it again next time! As I'm not in the WordPress world, many things are strange to me and I'm indebted to Jenny Wong for pointing me in the right direction on numerous occasions and being very patient with my questions! Thanks Jenny!

Project organisation

There's always ancillary files and directories in a project that aren't part of the actual website, so I have put the WordPress site in a subdirectory called app and then I have room for other stuff. My project's root directory looks like this:

$ tree . --dirsfirst -FL 1
.
├── app/
├── bin/
├── data/
├── docker/
├── README.md
└── docker-compose.yml

This is what each item is for:

  • app/ – The WordPress application files are in this directory.
  • bin/ – Useful command-line scripts
  • data/ – MySQL dump files go here.
  • docker/ – Files required by the Docker setup are in this directory.
  • README.md – Every project needs a README!
  • docker-compose.yml – Development orchestration config file.

I put everything into git, with a .gitignore file to ignore everything in data along with various other WordPress files/directories that shouldn't in version control.

Docker

A pair of Docker containers is used to run the site locally for development. I'm slowly getting my feet wet with Docker, so I'm not sure if this is the best way to do things. The docker-compose command allows you to spin up multiple containers in one go and join them together. This is done via the docker-compose.yml file.

Mine looks like this:

docker-compose.yml:

version: '3'

services: db: image: mysql:5.7 ports: - 127.0.0.1:3306:3306 command: [ '--default_authentication_plugin=mysql_native_password', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci' ] volumes: - db_data:/var/lib/mysql environment: MYSQL_DATABASE: wordpress MYSQL_ROOT_PASSWORD: 123456

wp: build: context: ./docker dockerfile: Dockerfile-wp ports: - 127.0.0.1:80:80 volumes: - ./docker/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini - ./app:/var/www/html depends_on: - db links: - db environment: DB_NAME: wordpress DB_USER: root DB_PASSWORD: 123456 DB_HOST: db WP_DEBUG: 1 LIVE_URL: https://project1.com DEV_URL: http://dev.project1.com

volumes: db_data: # store database into a volume so that we can pause the containers

There are two containers: wp for the Apache/PHP and db for the MySQL.

The db container

The db container uses the default Docker MySQL container. I picked version 5.7 as that's what's running in my live environment. As this is a single-purpose development container, I just use the MySQL root user and set its password.

I want to persist the MySQL database between invocations of the container, so to do this, I create a volume called db_data and then map the /var/lib/mysql directory to that volume. I also expose MySQL on 3306 so that I can connect to it from my desktop.

The wp container

For the wp container, I start with the default Docker WordPress container and add XDebug and the WP-CLI to it. This is done in the ./docker/Dockerfile-wp file:

./docker/Dockerfile-wp:

FROM wordpress:php7.3-apache

# Install xdebug RUN pecl install xdebug && docker-php-ext-enable xdebug

# Install Less for WP-CLI RUN apt-get update && apt-get -y install less

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

docker-compose will now create a container from our Dockerfile-wp and use that.

I map the docker/php.conf.ini into the container so that the PHP picks up our additional php.ini configuration settings:

docker/php.conf.ini:

upload_max_filesize = 10M
post_max_size = 10M

xdebug.overload_var_dump = 1 xdebug.remote_enable = 1 xdebug.remote_autostart = 0 xdebug.remote_connect_back =

Truncated by Planet PHP, read more at the original (another 5805 bytes)