WP with Compose
We have already installed docker compose
:
docker compose version
docker compose --help | less
1. Install a WP site
1.1 Create a project
-
Create a directory:
mkdir -p /var/compose/wordpress
cd /var/compose/wordpress/ -
Create the config file
compose.yml
:cat << '_EOF_' > compose.yml
services:
db:
image: mariadb
restart: unless-stopped
environment:
MARIADB_DATABASE: wp5db
MARIADB_USER: wp5user
MARIADB_PASSWORD: wp5pass
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: '1'
volumes:
- ./db:/var/lib/mysql
wp5:
image: wordpress
restart: unless-stopped
ports:
- 127.0.0.1:8086:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wp5db
WORDPRESS_DB_USER: wp5user
WORDPRESS_DB_PASSWORD: wp5pass
volumes:
- ./www:/var/www/html
_EOF_It is similar to the
docker create
commands that we have used previously.nano compose.yml
nano /var/docker/db1/create.sh
nano /var/docker/wp3/create.sh -
Start the services and look around:
docker compose up -d
ls
ls db/
ls www/
docker network ls
docker network inspect wordpress_default | less
docker compose ls
docker compose ps -a
docker compose logs db -f
docker compose logs wp5 -f
docker compose exec db bash
docker compose exec db mariadb
docker compose exec wp5 bash
docker compose --help | less
1.2 Setup reverse proxy
-
Create a site configuration on
nginx
:cd /etc/nginx/sites-available/
cp wp4 wp5
sed -i wp5 -e 's/wp4/wp5/g'
nano wp5Make sure to use the correct port on
proxy_pass
:proxy_pass http://127.0.0.1:8086;
-
Enable it:
cd ../sites-enabled/
ls ../sites-available/wp5
ln -s ../sites-available/wp5 .
ls -l -
Get an SSL certificate:
domain=wp5.user1.fs.al
email=dashohoxha@gmail.com
certbot certonly --webroot -w /var/www \
-d $domain,www.$domain --dry-run
certbot certonly --webroot -w /var/www \
-d $domain,www.$domain -m $email --agree-tos
certbot certificates -
Reload
nginx
:nginx -t
systemctl reload nginx
1.3 Installation wizard
Open in browser https://wp5.user1.fs.al and complete the installation wizard.
1.4 Use an env file
Let's use an environment file for the settings:
-
Stop the containers and destroy them:
docker compose down
It will remove the network as well, but not the data volumes/directories.
-
Create the file
db.env
:cat << '_EOF_' > db.env
DBNAME=wp5db
DBUSER=wp5user
DBPASS=wp5pass
_EOF_ -
Modify
compose.yml
by addingenv_file: db.env
to each service, and by using the DB env variables:services:
db:
image: mariadb
restart: unless-stopped
env_file: db.env
environment:
MARIADB_DATABASE: ${DBNAME:-wp5db}
MARIADB_USER: ${DBUSER:-wp5user}
MARIADB_PASSWORD: ${DBPASS:-wp5pass}
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: '1'
volumes:
- ./db:/var/lib/mysql
wp5:
image: wordpress
restart: unless-stopped
ports:
- 127.0.0.1:8086:80
env_file: db.env
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${DBNAME:-wp5db}
WORDPRESS_DB_USER: ${DBUSER:-wp5user}
WORDPRESS_DB_PASSWORD: ${DBPASS:-wp5pass}
volumes:
- ./www:/var/www/html
depends_on:
- db -
Run the containers:
docker compose up -d
Check also https://wp5.user1.fs.al in browser.
1.5 Use custom names
-
The default name of the project is the name of the directory where the configuration file is located. It can be specified using the option
-p
on the commanddocker compose
, or using the fieldname:
on the configuration file:docker compose ls
docker compose ps
docker network ls
docker compose down
sed -i compose.yml -e '1i name: wp'
head compose.yml
docker compose up -d
docker compose ls
docker compose ps
docker network ls -
To set the name of the default network we can add something like this:
networks:
default:
name: wp-netdocker compose down
cat << _EOF_ >> compose.yml
networks:
default:
name: wp-net
_EOF_
tail compose.yml
nano compose.yml
docker compose up -d
docker network ls -
To set the name of a container we can use the field
container_name:
like thisname: wp
services:
db:
image: mariadb
container_name: mariadb1
# . . . . . . . . . .
wp5:
image: wordpress
container_name: wp5
# . . . . . . . . . .docker compose down
nano compose.yml
docker compose up -d
docker compose ps
1.6 Build custom image
The default WP image that we are using, wordpress:latest
, does not
have the tool wp-cli
installed inside it. We want to build and use a
custom image that has wp-cli
installed as well.
-
Let's start by creating this
Dockerfile
:cat << '_EOF_' > Dockerfile
# syntax=docker/dockerfile:1.4
FROM wordpress:latest
RUN <<EOF
apt update
apt upgrade --yes
# install less and mariadb-client
apt install --yes less mariadb-client
# install wp-cli
curl -s -o /usr/local/bin/wp \
https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x /usr/local/bin/wp
EOF
_EOF_nano Dockerfile
-
Stop and remove the current project:
docker compose down
-
Add the field
build: .
tocompose.yml
, like this:wp5:
build: .
image: wordpress:local
container_name: wp5In this case,
build:
shows the directory where theDockerfile
is located (.
is the current directory). -
Build and start the project:
docker compose up -d
Notice that it will build first the image
wordpress:local
because it is not available.docker image ls
docker compose ps -
Let's try
wp-cli
:docker compose exec -u www-data wp5 wp
docker compose exec -u www-data wp5 wp user listCreate an alias:
alias wp5cli='docker compose exec -u www-data wp5 wp'
alias
wp5cli user listAdd this alias to
~/.bashrc_custom
as well.
2. Install another WP site
We can create another compose project, another directory with another
config file compose.yml
, similar to the current one. In this case it
will start another MariaDB container and another WP container.
But we can also install it on the same project, using the same MariaDB container. Let's try this approach because using a common MariaDB container is a bit more efficient than using separate ones, and because it is more didactic (we can learn more).
-
First, let's rename the directory
www
towp5
and the filedb.env
towp5db.env
:docker compose down
mv www wp5
mv db.env wp5db.env
sed compose.yml -e 's#\./www:#./wp5:#' -e 's/db\.env/wp5db.env/'
sed -i compose.yml -e 's#\./www#./wp5#' -e 's/db\.env/wp5db.env/'
sed compose.yml -n -e '/volumes:/,+2 p' -e '/env_file:/ p'
docker compose up -d -
Then create the file
wp6db.env
:cat << EOF > wp6db.env
DBNAME=wp6db
DBUSER=wp6user
DBPASS=wp6pass
EOFcat wp6db.env
-
Create a new database and user on the container
mariadb1
:cat << '_EOF_' > wp6db.sh
#!/bin/bash -x
source wp6db.env
DBCONTAINER="mariadb1"
mariadb="docker exec -i $DBCONTAINER mariadb"
cat <<EOF | tee /dev/tty | $mariadb
create database $DBNAME;
create user '$DBUSER'@'%' identified by '$DBPASS';
grant all on $DBNAME.* to '$DBUSER'@'%';
flush privileges;
EOF
_EOF_nano wp6db.sh
chmod +x wp6db.sh
./wp6db.sh
echo "show databases;" \
| docker exec -i mariadb1 mariadb -
Add this service definition to
compose.yml
:wp6:
build: .
image: wordpress:local
container_name: wp6
restart: unless-stopped
ports:
- 127.0.0.1:8087:80
env_file: wp6db.env
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${DBNAME:-wp6db}
WORDPRESS_DB_USER: ${DBUSER:-wp6user}
WORDPRESS_DB_PASSWORD: ${DBPASS:-wp6pass}
volumes:
- ./wp6:/var/www/htmldocker compose down
nano compose.yml
docker compose up -d
ls
ls wp6/
docker compose ps -
Create a reverse proxy site for it:
cd /etc/nginx/sites-available/
ls
cp wp5 wp6
sed -i wp6 -e 's/wp5/wp6/g' -e 's/8086/8087/'
nano wp6
cd ../sites-enabled/
ls ../sites-available/wp6
ln -s ../sites-available/wp6 .
ls -l
nginx -t
certbot certonly --webroot -w /var/www/ \
-d wp6.user1.fs.al,www.wp6.user1.fs.al \
-m dashohoxha@gmail.com --agree-tos
certbot certificates
nginx -t
systemctl reload nginx -
Open https://wp6.user1.fs.al in browser and finish the installation.
4. Maintenance
4.1 Backup
-
Create a backup script:
cat << '_EOF_' > ~/wp-backup.sh
#!/bin/bash -x
cd /var/compose/wordpress/
docker compose down
tar cfz ~/wp-$(date +%Y%m%d).tgz -C /var/compose/ wordpress/
docker compose up -d
_EOF_ -
Make the backup:
cd
nano wp-backup.sh
chmod +x wp-backup.sh
./wp-backup.sh
ls -lh wp-*.tgz
tar tvfz wp-20250210.tgz | less
4.2 Restore
-
Remove WP:
cd /var/compose/wordpress/
docker compose down
cd ..
rm -rf wordpress/
ls -
Restore from the backup:
ls ~/wp-*.tgz
tar xfz /root/wp-20250210.tgz -C /var/compose/
ls /var/compose/
cd /var/compose/wordpress/
ls
docker compose up -d
4.3 Backup DB
-
Create a backup script:
cat << '_EOF_' > db-backup.sh
#!/bin/bash -x
systemctl stop nginx
wp5cli='docker compose exec -u www-data wp5 wp'
$wp5cli db export db.sql
wp6cli='docker compose exec -u www-data wp6 wp'
$wp6cli db export db.sql
systemctl start nginx
_EOF_ -
Make the backup:
nano db-backup.sh
chmod +x db-backup.sh
db-backup.sh
ls wp5/
ls wp6/
nano wp6/db.sql
Usually we need a backup of the database when we need to change the version of MariaDB container. If we upgrade it, usually it can be done autommatically. However if we need to downgrade, we may have to install a fresh DB and then restore the content of the DB from the backup.
4.4 Update
-
Update apps:
cat << '_EOF_' > update.sh
#!/bin/bash -x
wp5cli='docker compose exec -u www-data wp5 wp'
wp6cli='docker compose exec -u www-data wp6 wp'
systemctl stop nginx
$wp5cli core update
$wp5cli core update-db
$wp5cli plugin update --all
$wp5cli theme update --all
$wp5cli cache flush
$wp6cli core update
$wp6cli core update-db
$wp6cli plugin update --all
$wp6cli theme update --all
$wp6cli cache flush
systemctl start nginx
_EOF_nano update.sh
chmod +x update.sh
./update.sh -
Update docker images:
docker pull mariadb
docker pull wordpress
cd /var/compose/wordpress/
docker compose build
docker compose up -d