WordPress with Docker
We are going to create a MariaDB container and two WordPress
containers (for the domains wp3.user1.fs.al
and
wp4.user1.fs.al
). And because the WP containers need to communicate
with the DB container, we will also create a docker (virtual) network,
where all the three containers will be connected.
We are going to use the existing nginx
as a reverse proxy for these
two sites. Ideally, we should also containerize the reverse proxy, but
let's keep it simple for the time being.
1. Create a network
docker network ls
docker network create wpnet
docker network ls
docker network inspect wpnet | less
2. Create a MariaDB container
-
We can download and use the official mariadb image:
docker search mariadb | less
docker pull mariadb
docker image ls
docker image history mariadb | lessIt is official because it is maintained by the MariaDB foundation.
-
Let's create a directory for this container:
mkdir -p /var/docker/db1
cd /var/docker/db1 -
Create a container:
cat <<'_EOF_' > create.sh
#!/bin/bash -x
mkdir -p data
docker create \
--name db1 \
--hostname mariadb \
--network wpnet \
--network-alias mariadb1 \
--mount type=bind,source=$(pwd)/data,destination=/var/lib/mysql \
--restart unless-stopped \
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
mariadb:latest
_EOF_nano create.sh
chmod +x create.sh
./create.sh
docker ps -a -
Start and test the container:
docker start db1
docker ps
docker logs db1 -f
ls data/
docker exec -it db1 mariadb
show databases;
exit
3. Install WP3
-
Let's create a directory for it:
mkdir -p /var/docker/wp3
cd /var/docker/wp3/ -
Create also a MariaDB database and user:
docker exec -it db1 mariadb
CREATE DATABASE wp3db;
show databases;
CREATE USER 'wp3user'@'%' IDENTIFIED BY 'wp3pass';
select user, host from mysql.user;
GRANT ALL ON wp3db.* TO 'wp3user'@'%';
show grants for 'wp3user'@'%';
FLUSH PRIVILEGES;
exit; -
We can download and use the official wordpress image:
docker search wordpress | less
docker pull wordpress
docker image ls
docker image history wordpress | lessThis image includes Apache2, PHP and the WP application files.
-
Create a container:
cat <<'_EOF_' > create.sh
#!/bin/bash -x
mkdir -p www
docker create \
--name wp3 \
--hostname wp3 \
--network wpnet \
--publish 127.0.0.1:8083:80 \
--mount type=bind,source=$(pwd)/www,destination=/var/www/html \
--env WORDPRESS_DB_HOST=mariadb1 \
--env WORDPRESS_DB_NAME=wp3db \
--env WORDPRESS_DB_USER=wp3user \
--env WORDPRESS_DB_PASSWORD=wp3pass \
--restart unless-stopped \
wordpress:latest
_EOF_nano create.sh
chmod +x create.sh
./create.sh
docker ps -a -
Start it:
docker start wp3
docker logs wp3 -f
ls
ls www/
nano www/wp-config.phpTest it with
w3m
:apt list w3m
apt install w3m
w3m http://127.0.0.1:8083 # use 'q' to exit -
Create a new site on the reverse proxy:
cd /etc/nginx/sites-available/
cp wp2 wp3
sed -i wp3 -e 's/wp2/wp3/g'
nano wp3Edit
wp3
and make sure that theproxy_pass
line looks like this:proxy_pass http://127.0.0.1:8083;
Enable this site:
cd ../sites-enabled/
ln -s ../sites-available/wp3 .
nginx -t -
Get an SSL cert for the new site:
certbot certonly \
--webroot -w /var/www \
-d wp3.user1.fs.al,www.wp3.user1.fs.al \
--dry-run
certbot certonly \
--webroot -w /var/www \
-d wp3.user1.fs.al,www.wp3.user1.fs.al \
-m dashohoxha@gmail.com \
--agree-tos
certbot certificatesReload
nginx
:nginx -t
systemctl reload nginx -
Open in browser https://wp3.user1.fs.al and complete the installation wizard.
4. Install WP4
-
Create a directory for it:
mkdir -p /var/docker/wp4
cd /var/docker/wp4/ -
Create a MariaDB database and user:
cat <<'_EOF_' > db-init.sh
#!/bin/bash -x
DBNAME="wp4db"
DBUSER="wp4user"
DBPASS="wp4pass"
DBCONTAINER="db1"
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 db-init.sh
chmod +x db-init.sh
./db-init.sh
echo 'show databases;' \
| docker exec -i db1 mariadb -
Create a WP container:
cat <<'_EOF_' > create.sh
#!/bin/bash -x
DBHOST='mariadb1'
DBNAME='wp4db'
DBUSER='wp4user'
DBPASS='wp4pass'
mkdir -p www
docker create \
--name wp4 \
--hostname wp4 \
--network wpnet \
--publish 127.0.0.1:8084:80 \
--mount type=bind,source=$(pwd)/www,destination=/var/www/html \
--env WORDPRESS_DB_HOST=$DBHOST \
--env WORDPRESS_DB_NAME=$DBNAME \
--env WORDPRESS_DB_USER=$DBUSER \
--env WORDPRESS_DB_PASSWORD="$DBPASS" \
--restart unless-stopped \
wordpress:latest
_EOF_nano create.sh
chmod +x create.sh
./create.sh
docker ps -a -
Start it:
docker start wp4
docker logs wp4 -f
ls www/
ls -al www/
w3m http://127.0.0.1:8084 -
Create a new nginx site:
cd /etc/nginx/sites-available/
cp wp3 wp4
sed -i wp4 -e 's/wp3/wp4/g' -e 's/8083/8084/'
nano wp4
cd ../sites-enabled/
ln -s ../sites-available/wp4 .
nginx -t -
Get an SSL cert and reload
nginx
:domain=wp4.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 certificatesnginx -t
systemctl reload nginx -
Open in browser https://wp4.user1.fs.al and complete the installation wizard.
5. Maintenance
Logs:
docker logs db1 -f
docker logs wp4 -f
5.1 wp-cli
The tool wp-cli
is crucial for the mantenance of a WP site. Let's
make a script that runs it:
cat <<'_EOF_' > /var/docker/wp4/wp-cli.sh
#!/bin/bash
DBHOST='mariadb1'
DBNAME='wp4db'
DBUSER='wp4user'
DBPASS='wp4pass'
docker run -it --rm \
--user 33:33 \
--volumes-from wp4 \
--network container:wp4 \
--env WORDPRESS_DB_HOST=$DBHOST \
--env WORDPRESS_DB_NAME=$DBNAME \
--env WORDPRESS_DB_USER=$DBUSER \
--env WORDPRESS_DB_PASSWORD="$DBPASS" \
--env HOME=/tmp \
wordpress:cli "$@"
_EOF_
cd /var/docker/wp4/
chmod +x wp-cli.sh
./wp-cli.sh --help
./wp-cli.sh user list
5.2 Backup
-
Let's create a backup script:
cat <<'_EOF_' > ~/wp4-backup.sh
#!/bin/bash -x
systemctl stop nginx
cd /var/docker/wp4/
./wp-cli.sh db export db.sql
cd ..
tar cfz wp4-$(date +%Y%m%d).tgz wp4/
mv *.tgz ~/
systemctl start nginx
_EOF_ -
Test it:
nano ~/wp4-backup.sh
chmod +x ~/wp4-backup.sh
~/wp4-backup.sh
ls -lh ~/
tar tvfz ~/wp4-20250210.tgz | less
5.3 Restore
-
Uninstall WP4:
cat <<'_EOF_' > ~/wp4-remove.sh
#!/bin/bash -x
docker stop wp4
docker rm wp4
rm -rf /var/docker/wp4/
DBNAME="wp4db"
DBUSER="wp4user"
DBPASS="wp4pass"
DBCONTAINER="db1"
mariadb="docker exec -i $DBCONTAINER mariadb"
cat <<EOF | tee /dev/tty | $mariadb
revoke all privileges, grant option from '$DBUSER'@'%';
drop user '$DBUSER'@'%';
drop database $DBNAME;
EOF
_EOF_nano ~/wp4-remove.sh
chmod +x ~/wp4-remove.sh
~/wp4-remove.sh -
Restore from the backup:
cd /var/docker/
tar xfz ~/wp4-*.tgz
ls
cd wp4/
ls
./db-init.sh
./create.sh
docker ps -a
docker start wp4
# open https://wp4.user1.fs.al in browser and finish the installation
# import the DB backup
ls www/
ls -lh www/db.sql
./wp-cli.sh db import db.sql
5.4 Update
-
Update WP files:
systemctl stop nginx
# Update WordPress core
./wp-cli.sh core version
./wp-cli.sh core update
./wp-cli.sh core update-db
# Update all plugins
./wp-cli.sh plugin update --all
# Update all themes
./wp-cli.sh theme update --all
# Clear cache
./wp-cli.sh cache flush
systemctl start nginx -
Update docker image:
docker pull wordpress:latest
docker image ls
docker stop wp4
docker rm wp4
cd /var/docker/wp4/
./create.sh
docker start wp4This is the equivalent of
apt update && apt upgrade
for docker containers.We destroy and recreate the container, however the DB and the WP files will be the same as before, because they are outside the container.