Yet another how to run WordPress with Docker tutorial

by

in

There are already a lot of tutorials on how to run a WordPress blog from a Docker image. This one is more of the same and yet a little different.

The usual approach includes a full stack containing WordPress as well as a database (e.g., MySQL, MariaDB, Postgres, etc.). However, since I was planning on using the datbase for more than just WordPress, i thought it might be prudent to run an instance of MariaDB on the host rather than spin up a database in each container.

That being said, here’s the docker-compose.yml file I’m using to spin up my blog.

services:

  wordpress:
    image: wordpress:6.5.3-apache
    container_name: mtnr-wordpress
    restart: always
    ports:
      - 8001:80
    env_file:
      - .env
    environment:
      WORDPRESS_DB_HOST: host.docker.internal:3306
      WORDPRESS_DB_USER: $MYSQL_USER
      WORDPRESS_DB_PASSWORD: $MYSQL_PASSWORD
      WORDPRESS_DB_NAME: mtnr
      WORDPRESS_CONFIG_EXTRA: |
        define( 'WP_REDIS_HOST', 'mtnr-redis' );
    volumes:
      - wordpress:/var/www/html
    extra_hosts:
      - host.docker.internal:host-gateway

  database-relay:
    image: alpine/socat:1.8.0.0
    container_name: mtnr-database-relay
    network_mode: host
    command: TCP-LISTEN:3306,fork,bind=host.docker.internal TCP-CONNECT:127.0.0.1:3306
    extra_hosts:
      - host.docker.internal:host-gateway

  redis:
    image: redis:7.2.5
    container_name: mtnr-redis
    restart: always

volumes:
  wordpress:

A few things worth mentioning here. For starters, all three services make use of a dedicated version in favor of latest in order to avoid any breaking changes when restarting the service. Let’s look at each service in a little bit more detail.

Starting from the top with the WordPress service.

Sensitive data such as $MYSQL_USER and $MYSQL_PASSWORD will be provided as environment variables via an .env file stored in the same location as the docker-compose.yml file.

WORDPRESS_DB_HOST points to host.docker.internal. The URL is provided as an extra host matching the host gateway. Since the database on the host listens to 127.0.0.1, simply adding the host gateway alone won’t solve our problem of connecting to the host database.

This is where socat comes into play.

You can read about this in detail here: https://dev.to/mjnaderi/accessing-host-services-from-docker-containers-1a97.

I added redis for object caching, too. This seems pretty straight forward. However, on order for WordPress, or rather a redis object cache plugin recognize the redis container, we must add the container name to WordPress’ config via adding the WP_REDIS_HOST variable to the WORDPRESS_CONFIG_EXTRA environmen variable.

All WordPress files will be stored in a volume called wordpress, which about sums it up.

All there is left to do is to start up the containers (-d as in detached).

sudo docker compose up -d

Further reading:


Comments

Leave a Reply

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