I’m going to assume you have some experience with Docker and so will be glossing over alot of stuff.
First Up, Traefik
Traefik in this setup is being used as a reverse proxy which allows us to run multiple services on our server without having to expose a ton of ports, and it handles things like ssl and domain configuration for our services.
Create a new docker-compose.yml file
version: '3.8'
services:
traefik:
image: traefik:latest
restart: always
ports:
- 80:80
- 443:443
command:
- --accesslog
- --log.level=INFO
- --api.dashboard=true
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web-secure.address=:443
#- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
#- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
#- [email protected]
#- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik:/letsencrypt
labels:
- traefik.enable=true
- traefik.http.routers.api.rule=Host(`${TRAEFIK_URL}`)
- traefik.http.routers.api.entrypoints=web
- traefik.http.routers.api.service=api@internal
#- traefik.http.services.traefik.loadbalancer.server.port=8080
#- traefik.http.routers.api.entrypoints=web-secure
#- traefik.http.routers.api.tls=true
#- traefik.http.routers.api.tls.certresolver=letsencrypt
Next up WordPress
WordPress - Blogging platform
However I have added the additional configs, that I tent to add to a site to boost its performance, and I often test dev sites with these settings enabled so I know how a theme or plugin behaves before going public.
In the docker-compose.yml file add
wordpress:
image: wordpress:latest
restart: always
depends_on:
- mariadb
- redis
expose:
- 80
- 443
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_NAME: ${WP_DB_NAME}
WORDPRESS_DB_USER: ${WP_DB_USER}
WORDPRESS_DB_PASSWORD: ${WP_DB_PASSWORD}
WORDPRESS_TABLE_PREFIX: ${WP_DB_PREFIX}
WORDPRESS_CONFIG_EXTRA:
define( 'WP_HOME', 'http://${WP_WWW_URL}/' );
define( 'WP_SITEURL', 'http://${WP_WWW_URL}/' );
define( 'WP_REDIS_HOST', 'redis' );
define( 'WP_REDIS_PORT', 6379 );
define( 'COMPRESS_CSS', true );
define( 'COMPRESS_SCRIPTS', true );
define( 'CONCATENATE_SCRIPTS', true );
define( 'ENFORCE_GZIP', true );
define( 'AUTOSAVE_INTERVAL', 120 );
define( 'WP_POST_REVISIONS', 10);
define( 'EMPTY_TRASH_DAYS', 30 );
define( 'IMAGE_EDIT_OVERWRITE', true );
define( 'DISALLOW_FILE_EDIT', true );
volumes:
- wordpress:/var/www/html
- ./wordpress/wp-content:/var/www/html/wp-content
- ./wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
labels:
- traefik.enable=true
- traefik.http.routers.wordpress.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
- traefik.http.routers.wordpress.entrypoints=web
#- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
#- traefik.http.routers.wordpress.middlewares=redirect-to-https@docker
#- traefik.http.routers.wordpress-secure.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
#- traefik.http.routers.wordpress-secure.entrypoints=web-secure
#- traefik.http.routers.wordpress-secure.tls.certresolver=letsencrypt
expose:
- 80
- 443
This is refering to the default internal port of the docker image and is not publicly accessible, in this use case it mainly serves to document the port being used.
volumes:
- wordpress:/var/www/html
- ./wordpress/wp-content:/var/www/html/wp-content
- ./wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
Volumes are where your wordpress content is stored. ./
Denotes a local folder on the machine, in this case wp-content
The first declaration is for the entire wordpress install.
Last line allows for custom php settings to be loaded.
labels:
- traefik.enable=true
- traefik.http.routers.wordpress.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
- traefik.http.routers.wordpress.entrypoints=web
#- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
#- traefik.http.routers.wordpress.middlewares=redirect-to-https@docker
#- traefik.http.routers.wordpress-secure.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
#- traefik.http.routers.wordpress-secure.entrypoints=web-secure
#- traefik.http.routers.wordpress-secure.tls.certresolver=letsencrypt
labels
pass information about the service to traefik
so that it can be proxied, services that do not specify a label arent proxied by traefik. The parts that are commented out are for https.
In the same folder as the docker-compose.yml file, create a new file called wordpress.ini and paste the following
file_uploads = On
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 256M
max_execution_time = 300
Next up MYSQL and Adminer
WordPress can’t function without a database, so lets set that up. Adminer is effectively the same as phpmyadmin, just much lighterweight.
So in the docker-compose.yml file add
mariadb:
image: mariadb:latest
restart: always
expose:
- 3306
environment:
MYSQL_DATABASE: ${WP_DB_NAME}
MYSQL_USER: ${WP_DB_USER}
MYSQL_PASSWORD: ${WP_DB_PASSWORD}
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- mariadb:/var/lib/mysql
adminer:
image: adminer:latest
restart: always
depends_on:
- mariadb
expose:
- 8080
labels:
- traefik.enable=true
- traefik.http.routers.adminer.rule=Host(`${ADMINER_URL}`)
- traefik.http.routers.adminer.entrypoints=web
#- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
#- traefik.http.routers.adminer.middlewares=redirect-to-https@docker
#- traefik.http.routers.adminer-secure.rule=Host(`${ADMINER_URL}`)
#- traefik.http.routers.adminer-secure.entrypoints=web-secure
#- traefik.http.routers.adminer-secure.tls.certresolver=letsencrypt
Next create a .env file and add the following
# WordPress
WP_DB_NAME=wp-dev-db
WP_DB_PREFIX=wp_
WP_DB_USER=wp-dev-user
WP_DB_PASSWORD=wp-dev-pass
# Traefik Domains
WP_URL=wpdev.test
WP_WWW_URL=www.wpdev.test
TRAEFIK_URL=traefik.wpdev.test
ADMINER_URL=adminer.wpdev.test
Finally lets add Redis
Redis is a database cache, to put it as simply as possible.
In the docker-compose.yml file add
redis:
image: redis:latest
restart: always
expose:
- 6379
command:
- redis-server
- --save 60 1
- --loglevel warning
- --maxmemory 128mb
- --maxmemory-policy allkeys-lru
volumes:
- redis:/var/lib/redis
- redis:/data
#- ./redis.conf:/usr/local/etc/redis/redis.conf
./redis.conf:/usr/local/etc/redis/redis.conf
If you want to customize redis beyond the commands that I have added you can load a custom config file and uncomment out this line. Ensure that the file is in the same folder as the docker-compose file.
Finally at the bottom you decalre all your enabled Volumes
volumes:
traefik:
wordpress:
mariadb:
redis:
At the end your docker-compose file should look like this
version: '3.8'
services:
traefik:
image: traefik:latest
restart: always
ports:
- 80:80
- 443:443
command:
- --accesslog
- --log.level=INFO
- --api.dashboard=true
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web-secure.address=:443
#- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
#- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
#- [email protected]
#- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik:/letsencrypt
labels:
- traefik.enable=true
- traefik.http.routers.api.rule=Host(`${TRAEFIK_URL}`)
- traefik.http.routers.api.entrypoints=web
- traefik.http.routers.api.service=api@internal
#- traefik.http.services.traefik.loadbalancer.server.port=8080
#- traefik.http.routers.api.entrypoints=web-secure
#- traefik.http.routers.api.tls=true
#- traefik.http.routers.api.tls.certresolver=letsencrypt
wordpress:
image: wordpress:latest
restart: always
depends_on:
- mariadb
- redis
expose:
- 80
- 443
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_NAME: ${WP_DB_NAME}
WORDPRESS_DB_USER: ${WP_DB_USER}
WORDPRESS_DB_PASSWORD: ${WP_DB_PASSWORD}
WORDPRESS_TABLE_PREFIX: ${WP_DB_PREFIX}
WORDPRESS_CONFIG_EXTRA:
define( 'WP_HOME', 'http://${WP_WWW_URL}/' );
define( 'WP_SITEURL', 'http://${WP_WWW_URL}/' );
define( 'WP_REDIS_HOST', 'redis' );
define( 'WP_REDIS_PORT', 6379 );
define( 'COMPRESS_CSS', true );
define( 'COMPRESS_SCRIPTS', true );
define( 'CONCATENATE_SCRIPTS', true );
define( 'ENFORCE_GZIP', true );
define( 'AUTOSAVE_INTERVAL', 120 );
define( 'WP_POST_REVISIONS', 10);
define( 'EMPTY_TRASH_DAYS', 30 );
define( 'IMAGE_EDIT_OVERWRITE', true );
define( 'DISALLOW_FILE_EDIT', true );
volumes:
- wordpress:/var/www/html
- ./wordpress/wp-content:/var/www/html/wp-content
- ./wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
labels:
- traefik.enable=true
- traefik.http.routers.wordpress.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
- traefik.http.routers.wordpress.entrypoints=web
#- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
#- traefik.http.routers.wordpress.middlewares=redirect-to-https@docker
#- traefik.http.routers.wordpress-secure.rule=Host(`${WP_URL}`, `${WP_WWW_URL}`)
#- traefik.http.routers.wordpress-secure.entrypoints=web-secure
#- traefik.http.routers.wordpress-secure.tls.certresolver=letsencrypt
mariadb:
image: mariadb:latest
restart: always
expose:
- 3306
environment:
MYSQL_DATABASE: ${WP_DB_NAME}
MYSQL_USER: ${WP_DB_USER}
MYSQL_PASSWORD: ${WP_DB_PASSWORD}
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- mariadb:/var/lib/mysql
adminer:
image: adminer:latest
restart: always
depends_on:
- mariadb
expose:
- 8080
labels:
- traefik.enable=true
- traefik.http.routers.adminer.rule=Host(`${ADMINER_URL}`)
- traefik.http.routers.adminer.entrypoints=web
#- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
#- traefik.http.routers.adminer.middlewares=redirect-to-https@docker
#- traefik.http.routers.adminer-secure.rule=Host(`${ADMINER_URL}`)
#- traefik.http.routers.adminer-secure.entrypoints=web-secure
#- traefik.http.routers.adminer-secure.tls.certresolver=letsencrypt
redis:
image: redis:latest
restart: always
expose:
- 6379
command:
- redis-server
- --save 60 1
- --loglevel warning
- --maxmemory 128mb
- --maxmemory-policy allkeys-lru
volumes:
- redis:/var/lib/redis
- redis:/data
#- ./redis.conf:/usr/local/etc/redis/redis.conf
volumes:
traefik:
wordpress:
mariadb:
redis:
Then you go to your terminal and type
docker-compose up -d
You can now visit WordPress at the url you set, and proceed through the installation.
To get Redis working with WordPress, you need to download the Redis Object Cache plugin.
Simply goto Plugins > Add New and search for Redis Object Cache and Install. Then go to Settings > Redis > Enable Object Cache you should see