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:
- https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose
- https://devtidbits.com/2019/11/02/customise-wordpress-on-docker/
- https://riteshkhanna.com/2021/11/17/wordpress-using-awsdockerredis/
- https://stackoverflow.com/questions/75794951/apache2-as-proxy-to-a-docker-container-and-https-and-php-rewriting-http-to-http
Leave a Reply