Dropping in a PHP container
Written by Bunkers on February 27, 2017
This is the fourth post in my series about running a Docker based WordPress development environment. Yesterday I left it in a bit of a strange state, but all being well, you'll have a docker-compose
setup that manipulates two containers. One for the database and the other for our data, or application file system.
This doesn't do much, so today I want to add in our PHP container. This will mean we are able to process PHP code. In the next post we'll add the fourth, and final, container running NGINX as our web server. That will mean we have a full working PHP environment. So, let's start by looking at our PHP container.
I'd hoped that we could just use an official PHP image for the PHP container, but WordPress (and probably most other PHP applications) requires the installation of extensions like GD for images and the MySQL driver. So we need to create our own image, but as this is just using a Dockerfile it's simple to do.
Create a directory called php
alongside our other two image folders, percona
and site
. In it create a file called Dockerfile
with the following contents:
FROM php:7.1-fpm # install the PHP extensions we need RUN set -ex; \ \ apt-get update; \ apt-get install -y \ libjpeg-dev \ libpng12-dev \ libcurl4-openssl-dev \ ; \ rm -rf /var/lib/apt/lists/*; \ \ docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ docker-php-ext-install gd mysqli opcache curl # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php RUN { \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.interned_strings_buffer=8'; \ echo 'opcache.max_accelerated_files=4000'; \ echo 'opcache.revalidate_freq=2'; \ echo 'opcache.fast_shutdown=1'; \ echo 'opcache.enable_cli=1'; \ } > /usr/local/etc/php/conf.d/opcache-recommended.ini VOLUME /var/www/html |
This is more involved than some of out other configuration files, but the majority should be familiar from the site
image's Dockerfile
yesterday. It starts by taking the official PHP 7.1 FPM image and installing the required libraries using apt-get
. The PHP image provides a command to enable the PHP extensions which is the next two lines. Lastly, we create a configuration file for OpCache. Enabling OpCache probably isn't strictly necessary, especially in a development environment, but it's good to show the principle and turning it off is as simple as removing opcache
from the docker-php-ext-install
command.
With this in place, we can add our PHP container to our docker-compose.yml
. The contents of which should now look like this:
version: '2' services: percona: build: ./percona ports: - "3306" env_file: ./db.env data: build: ./site env_file: - ./db.env - ./site/wp.env volumes: - /var/www/html - ./wp-content:/var/www/html/wp-content php: build: ./php volumes_from: - data links: - percona:wpdb env_file: ./db.env |
The new concept here is the links
section. This is a list of mappings from other container names to a name you want to use locally within the container. In this case, I'm setting a reference name of wpdb
to point to our percona
container. This means we can use wpdb
as the host name for the database in our wp-config.php
file.
It's time to test our new setup. If you still have everything running from yesterday, in the project directory, run:
docker-compose down |
Be careful with that command if you've done any work with the database container. It will stop the containers and delete them, so you will lose any data in the database! So far we've not put anything of worth in it, but if you've been experimenting then you might want to back up your data first.
Then, as before, run:
docker-compose up -d |
You should see a number of messages about building your PHP image and then the steps it takes to install the modules and configuration from the Dockerfile.
Just to check everything is working correctly, run:
docker-compose ps |
You'll see a table of our three containers. The data
container that has got an Exit
state, followed by our percona
and php
containers. These should both be Up
and have information about the ports they're exposing.
Despite having to create our own PHP image, it's still got applications beyond running WordPress. I like this as we're sticking to the idea of having images and containers with a single use. It also means the images we're creating are reusable.
I'm conscious this still doesn't do a great deal, but I also don't want to dump too much information in one post. Once we get the web server running and hooked up to our PHP container in my next post, then you'll have a full PHP development environment. Until then!