WordPress on Docker, the easy way (updated)

For this website I needed a CMS and a simple development environment. The easy pick was WordPress with Docker.

If you want this as well, just follow along…

Installing Docker

My loose interpretation of Docker.

First, let’s install Docker. Based on your environment there are roughly two version:

  • Docker Desktop for Windows and MacOS
  • Docker for Linux

They all can run Linux containers. This is what we are going to do as well with WordPress.

For now I will describe the procedure for Windows 10 and 11.

Installing Docker Desktop on Windows 10 and 11

Docker Desktop on Windows uses WSL2. This is a feature of Windows to run a lightweight VM with a Microsoft provided Linux Kernel with a distribution of choice. This VM is run on Hyper-V.

Installing WSL2

Let’s start with installing WSL2. If you already have a WSL2 distribution running, you can skip this of course.


Attention: When enabling WSL2 a Hyper-V hypervisor will be installed. If you have other VM software (like VirtualBox or VMWare) they might not work or run poorly until the Hyper-V hypervisor is disabled again. There is a “quick” way to disable the hypervisor temporary:

  • Open a Powershell terminal as a Administrator
  • Type in the following command:
bcdedit /set hypervisorlaunchtype off
  • Restart the computer (that’s the not quite quick part of it)

If you want to enable Hyper-V again, do like so:

  • Yet again, open a Powershell terminal as a Administrator
  • Now type in the command:
bcdedit /set hypervisorlaunchtype auto
  • Restart the computer…

Hyper-V should be enabled again. Back to our schedule after that detour!


So first things first, lets install WSL2.

(Just for reference, the official documentation for installing WSL(2) can be found at: Install WSL on Windows 10 | Microsoft Docs)

Installing WSL2 on Windows 10 2004 and newer and Windows 11

With the latest Windows 10 releases or Windows 11 installing WSL2 is just one simple command! You won’t get it easier than that. 👍

Open a Powershell terminal and type in the following command to enable WSL2 and install it with a distribution:

wsl --install

This will enable the Hyper-V Virtual Machine Platform, WSL and Ubuntu as the distribution. It will set it as a WSL2 distribution, ready to use with Docker Desktop. After running this command, restart the computer to get Hyper-V working.

If you fancy another distribution, just type it in after the install option, like:

wsl --install -d Debian

To get a list what ditributions are available, type in:

wsl --list --online

It will show a handy list of all the distributions available. Use the name under the NAME column when installing it with the wsl command.

Installation for Windows 10 1903 and 1909

If you are using a older Windows 10 version, use the instructions below.

Open a Powershell terminal and type in the following command to enable WSL:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

This will enable the WSL feature of Windows 10.

Okay, now we need the Virtual Machine platform for WSL2. So run the command:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

This will install the Hyper-V virtual machine platform. We need this to actually run WSL2.

For some reason, we will be missing the Linux kernel. So, download that as well:
https://aka.ms/wsl2kernel

To make everything easier, we set all WSL distribution to WSL2 with this command:

wsl --set-default-version 2

You can also set a distribution to WSL2 afterwards. This is a bit slower because it need to be converted then.

Okay, everything set. Reboot the computer. After some loading spinners (also know by me as concrete mixers), we are back.

Now open the Microsoft Store (you know that thing you might could get software from) and download a Linux distribution (it still feels quite strange). Search for instance for Debian or Ubuntu. A handy list of distributions is available at:
https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-6—install-your-linux-distribution-of-choice


When the computer has done its restart routine, open the distribution. It should be in the Start menu. You will be greeted with a command prompt asking for a username and password. These are for the WSL distribution. You can use whatever you like (as long as you can remember them). For you own sake, you can use these to get root access in the distribution with sudo, but no additional rights in Windows. So even as a root user in WSL, you can’t do any administrative stuff on Windows with it. How reassuring 😊.

After these steps, you should have WSL2 running.

Finally. On to Docker Desktop!

Installing Docker Desktop for Windows

Now that WSL2 is available, let’s get Docker running.
You could install Docker directly on the distribution… But, Docker Desktop has some nice integrations. And a shiny GUI. (That is running on Electron, because why shouldn’t it.)

Go to this website and click/tap/ENTER the nice big button to download Docker Desktop for Windows:
Docker Desktop for Mac and Windows | Docker

Let it install. If everything went correct, we see a little whale icon in the notification area. How nice!

And that was it for Docker Desktop. Sometimes things can be easy.

Setting up a WordPress docker container

Everything running? Let’s make that container and run WordPress.

Open up your Linux distribution and create a directory somewhere for the project. I will be using my home directory ~ make a directory projects and put every project in its own directory beneath. Something like:

mkdir ~/projects
cd ~/projects
mkdir wordpress
cd wordpress

Dockerfile

Let add some files for Docker. To create a file in the terminal, we use the program Nano. Just type nano following the filename to create or open a file for text editing. For this file type:

nano Dockerfile

Make sure that the D in Dockerfile is a capital D, otherwise Docker might complain a bit. The Nano editor opens with the empty file. Lets type (or copy and paste, what you fancy) the contents given below.

FROM wordpress:php7.4-apache


RUN pecl install xdebug
RUN docker-php-ext-enable xdebug

RUN adduser wordpress --group --system --uid 1000

This file is a Docker file. It tells Docker how to create our container. Let decipher all those magic words in the file:

CommandWhat does it do?
FROM wordpress:apacheDownloads the image with the tag apache from the wordpress repository Docker Hub.
You can find it here:
wordpress (docker.com)
The image with the tag apache will point to the latest WordPress release running on a Apache server.
RUN pecl install xdebugDownloads the XDebug extension from Pecl.
This is only needed when you want to debug PHP code (breakpoints and other nice things).
You can find it on the wide web here:
PECL :: Package :: xdebug (php.net)
RUN docker-php-ext-enable xdebugThis will enable the XDebug extension. It will be set as a extension for PHP.
RUN adduser wordpress –group –system –uid 1000We add a user with the name wordpress and with the UID of 1000. Why? Because when we want to modify files from our own Linux user account, the files should belong to our user.
About that number 1000. It might be different for you. Just run id in the distribution to find it out.

When all the nice words have been added to the file, exit Nano and choose to save the file. How? Just press CTRL + X on the keyboard. A question will appear at the bottom of the screen asking if we want to save the modified buffer. It’s a fancy way to say, that we have make some changes in memory (the so called buffer) and want that on the disk. Press Y to save the file with all modifications done.

That is all set. Now, we need two containers actually. One for PHP & Apache with WordPress and another with a database. That site needs some place to store all the things!

A easy way to do this is with Docker Compose files. A Docker Compose file consists of a list of so called services. Each service will run in its own container. For our WordPress we are going to make two services/containers. Add the following file to out project with Nano:

docker-compose.yml

version: "3.8"

services:
  wordpress:
    build:
      context: .
    ports:
      - 80:80
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_DEBUG=1
      - XDEBUG_MODE=debug
      - XDEBUG_CONFIG=client_host=host.docker.internal
    volumes:
      - ./wordpress:/var/www/html
    user: '1000'

  db:
    image: mariadb:latest
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  db:

Oh.. BTW, make sure to change that user parameter to the correct UID. It should be the same as in the Dockerfile file (Redundant name? Maybe).

This docker-compose.yml file will make two containers. The first, wordpress will use our Dockerfile:

build:
      context: .

That line will say: “To run this service, thou should build a container. Use thy context in the current directory.” Because we have a Dockerfile in the same directory, it will point to this file. When no filename is given in a context parameter, Docker will assume the filename Dockerfile. Watch that capital D!

What does this do?

volumes:
      - ./wordpress:/var/www/html

It will say, that the directory wordpress will be bind to the directory /var/www/html in the container. What this means for us is that every change made to our local wordpress directory will automatically apply inside the container. How do we know this magic /var/www/html directory? It is explained in the documentation of the WordPress image. Otherwise we need to figure this out on our own.

The other parameters will set environment variables for the process running in the containers, bind ports (so we can access the site on port 80) and add some volumes for the database.

With that set, lets make a wordpress directory.

mkdir wordpress

Not that everything is in place. The moment of truth… Run this command:

docker compose up

If everything went as planned, a WordPress site should be available on http://localhost.

The WordPress installer should pop up. Fill in the needed data and off you go!

But, how does WordPress know what database to use? Easy! In the docker-compose.yml file we have set via some environment variables every detail required. Just check the values under both environment parameters. Handy, huh? 🙂

When you have played around a bit with the site and want to stop running it, just execute the the command:

docker compose stop

This will stop all containers associated with the docker-compose file. When you feel the urge to run it again, just run the docker compose up command again and the containers will run, happy to serve your website.

When you want to remove those containers defined in the docker-compose.yml file, run this command:

docker compose down

This will remove the containers and all data volumes. For our little example this means all data in the database. Because the volume for the WordPress container is mounted to the local directory wordpress, those files will be left alone. Also, all Docker images downloaded and the one created for your website will still be available. You can see them in the Docker Desktop program or with the command:

docker image ls

With that settled, we have WordPress running. (And I have written my first page for this site….)

Hope that this tutorial did help you!

Leave a Reply

Your email address will not be published. Required fields are marked *