Step 1: Create a project directory
SSH to your server and start by creating a new project directory named wp-project
. You can also name it whatever you need.
mkdir wp-project
Step 2: Create Docker Compose YML File
Now navigate inside the project directory and create a new docker-compose.yml file with the following configuration.
cd wp-project
Create a new docker-compose.yml
file.
nano docker-compose.yml
Copy the entire contents below and paste it in the file.
Step 3: Configure Docker Compose
Make sure to replace the below mentioned environment variables.
version: "3.9"
services:
wordpress:
container_name: wordpress
image: wordpress:php8.1-apache
restart: always
stdin_open: true
tty: true
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_USER: db_user
WORDPRESS_DB_PASSWORD: db_user_pass
WORDPRESS_DB_NAME: db_name
volumes:
- wordpress_data:/var/www/html
- ./wordpress:/var/www/html
mariadb:
container_name: mariadb
image: mariadb
restart: always
environment:
MYSQL_DATABASE: db_name
MYSQL_USER: db_user
MYSQL_PASSWORD: db_user_pass
MYSQL_RANDOM_ROOT_PASSWORD: 'root_pass'
volumes:
- db_data:/var/lib/mysql
nginx:
container_name: nginx
image: nginx:latest
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- ./nginx/conf:/etc/nginx/conf.d
- ./certbot/conf:/etc/nginx/ssl
- ./certbot/data:/var/www/html
certbot:
container_name: certbot
image: certbot/certbot:latest
command: certonly --webroot --webroot-path=/var/www/html --email youremail@domain.com --agree-tos --no-eff-email -d domain.com -d www.domain.com
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/logs:/var/log/letsencrypt
- ./certbot/data:/var/www/html
volumes:
db_data:
wordpress_data:
Hit CTRL-X
followed by Y
and ENTER
to save and exit the file.
Docker Compose Configuration: Explanation
Here are the configuration details.
- version: Compose file version which is compatible with the Docker Engine. You can check compatibility here.
- services: here we have 4 services named
wordpress
,mariadb
,nginx
andcertbot
. - image: We use latest WordPress with PHP 8.1, Apache, Mariadb, Nginx and Certbot images available in Docker hub.
- volumes:
wordpress
: we have configured this directory to be synced with the directory we wish to use as the web root inside the container.conf
: here we will place the Nginx configuration file to be synced with the default Nginx conf.d folder inside the container.cedtbot/conf
: this is where we will receive the SSL certificate and this will be synced with the folder we wish to inside the container.ports
: configure the container to listen upon the listed ports.command
: the command used to receive the SSL certificate.
- environment: here we list all the environment variables that are available for the WordPress image.
WORDPRESS_DB_HOST
: Here we are using the service name of MariaDB container.WORDPRESS_DB_USER
: Same as the one we have configured in mariadb service.WORDPRESS_DB_PASSWORD
: Same as the one we have configured in mariadb service.WORDPRESS_DB_NAME
: Same as the one we have configured in mariadb service.
Step 4: Configure Nginx
As per the docker-compose.yml
configuration we need to create the default.conf
file inside the nginx/conf
directory.
Create the directory besides your docker-compose.yml
file to hold the configuration file.
mkdir -p nginx/conf
Create a file named default.conf
.
nano nginx/conf/default.conf
Place the following configurations, here we use reverse proxy configuration to wordpress container running Apache.
server {
listen [::]:80;
listen 80;
server_name domain.com www.domain.com;
root /var/www/html;
index index.php;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri @apache;
}
location ~ ^/.user.ini {
deny all;
}
location ~* .(svg|svgz)$ {
types {}
default_type image/svg+xml;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location @apache {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
location ~[^?]*/$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
location ~ .php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
}
Hit CTRL-X
followed by Y
and ENTER
to save and exit the file.
Now you have your docker-compose configuration and your Nginx configuration.
Step 4: Deploy WordPress with Docker Compose
Start the containers using the following command, you will receive the SSL certificates once the containers are started.
docker-compose up -d
Once all containers are started you will see two additional directories certbot
and wordpress
created alongside your docker-compose.yml
file.
The directory wordpress
holds all your WordPress website source code.
The directory certbot
holds all the files related to your SSL certificates.
To view the containers you can execute the following command.
docker-compose ps
Step 6: Configure Let’s Encrypt SSL with Nginx
As you have received the Let’s Encrypt SSL certificate you can configure HTTPS and setup redirection to HTTPS.
Edit the default.conf
and make the following changes.
nano nginx/conf/default.conf
server {
listen [::]:80;
listen 80;
server_name domain.com www.domain;
return 301 https://www.domain.com$request_uri;
}
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name domain.com;
ssl_certificate /etc/nginx/ssl/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/domain.com/privkey.pem;
return 301 https://www.domain.com$request_uri;
}
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name www.domain.com;
ssl_certificate /etc/nginx/ssl/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/domain.com/privkey.pem;
root /var/www/html;
index index.php;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri @apache;
}
location ~ ^/.user.ini {
deny all;
}
location ~* .(svg|svgz)$ {
types {}
default_type image/svg+xml;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location @apache {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
location ~[^?]*/$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
location ~ .php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://wordpress:80;
}
}
Hit CTRL-X
followed by Y
and ENTER
to save and exit the file.
Now restart the Nginx service to load the new configurations.
docker-compose restart nginx
Now you can check your domain name from your browser. You will get a redirection to HTTPS and you will see the WordPress installation page to complete the installation.
Troubleshooting
Below given some tips to SSH to containers, see error logs.
SSH to Docker Container
To SSH into wordpress
container, you can use the below command.
docker-compose exec wordpress /bin/bash
To SSH into nginx
container, you can use the below command.
docker-compose exec nginx /bin/bash
Check Container Logs
You can use the below command to check the logs of containers using docker-compose
docker-compose logs -f
Restart Containers
You can restart the containers using the restart
command easily.
docker-compose restart container_name
Replace container_name
with your container name (wordpress, nginx, certbot)
Stop all Docker Containers
You can stop all docker containers using the below command.
docker-compose down
Remove all Containers and Volumes
You can use docker-compose to remove all containers and their volumes with the below command.
docker compose rm -fv
Remove all Docker Containers
Remove all containers using the following command.
docker rm -f $(docker ps -a -q)
Delete all Volumes
You can also delete all volumes using the below command.
docker volume rm $(docker volume ls -q)
Start all Containers
With a single Docker compose command you can start all containers.
docker-compose up -d