Migrating A WordPress Website To Docker
Last Updated: April 17, 2024
Introduction –
In this tutorial you will learn how to migrate and dockerize a WordPress website and database from one host (such as On-Prem or a cloud provider like DigitalOcean). We will create three docker containers (mariadb, nginx, bitnami-php) using docker compose.
Export the WordPress Database from the current host
First, we need to login to the MySQL database, and export the current database.
Login to your current WordPress host via SSH, list the available databases and set the correct permissions for your wordpress SQL admin user:
1
2
3
4
5
mysql -u root -p
show databases;
GRANT PROCESS ON *.* TO '<username>'@localhost;
FLUSH PRIVILEGES;
EXIT;
Next, run the mysqldump command to Export the MySQL database to local storage. The following command will backup, export, and compress the backup database:
1
mysqldump --add-drop-table -h localhost -u <username> -p <database-name> | bzip2 -c > <db-backup-name>.bak.sql.bz2
Download the database backup to your local machine. For example, you can use MobaXterm establish an SSH connection to the virtual machine, then downloaded the file through the built-in SCP tab.
Note: Make sure to install bzip2 to zip the mysql database in 1 command.
1
sudo dnf install bzip2 -y
Export WordPress site data and html
We also need to zip and export the WordPress configuration files and plugins. The follow command will create an archive, output the progress, zips the files and directories, and sets a filename.
1
sudo tar cvzf /var/www/html/<wp-backup>.tar.gz /var/www/html/<wordpress-website>
Download the zipped WordPress databse archive to your local machine.
New Docker host - Create volumes for NGINX, PHP, and MariaDB containers
Now, we need to setup the docker host.
- Create a single volume group to encompass the entire sdb disk.
1
sudo vgcreate vg_sdb /dev/sdb
- Now create the logical volumes within vg_sdb.
1 2 3
sudo lvcreate -n lv_sdb1 -L 5G vg_sdb sudo lvcreate -n lv_sdb2 -L 2G vg_sdb sudo lvcreate -n lv_sdb3 -L 5G vg_sdb
- Identify the logical volumes on vda using the lvdisplay command.
1
sudo lvdisplay
- Create ext4 filesystems on these logical volumes using the mkfs.ext4 command. Here are the commands to do this:
1 2 3
sudo mkfs.ext4 /dev/vg_sdb/lv_sdb1 sudo mkfs.ext4 /dev/vg_sdb/lv_sdb2 sudo mkfs.ext4 /dev/vg_sdb/lv_sdb3
- Next, make new directories for the volumes to mount to and mount them:
1 2 3 4
sudo mkdir /nginx_html sudo mkdir /nginx_config sudo mkdir /mariadb_data sudo mount -a
Finally, we will make the newly created volumes automatically mount on boot. Open the fstab file with the sudo vi /etc/fstab
command, then add these lines to the end of the file:
1
2
3
/dev/vg_sdb/lv_sdb1 /nginx_html ext4 defaults 0 2
/dev/vg_sdb/lv_sdb2 /nginx_config ext4 defaults 0 2
/dev/vg_sdb/lv_sdb3 /mariadb_data ext4 defaults 0 2
Extract the zipped WordPress archive to /nginx_html
1
2
sudo mkdir /nginx_html/<wordpress-website>
sudo tar xvf <wp-backup>.tar.gz -C /nginx_html/<wordpress-website>
Now we need to set permissions on the nginx_html directory so that that PHP container can write to it:
1
2
cd /nginx_html
chown -R 1:1 .
Docker Setup
Create a new user-defined bridged network for Docker:
1
docker network create wordpress
Docker Compose configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: "3"
services:
mariadb:
image: mariadb:latest
container_name: mariadb
environment:
- MYSQL_ROOT_PASSWORD=<password>
volumes:
- /mariadb_data:/var/lib/mysql
networks:
- wordpress
nginx:
image: nginx:latest
container_name: nginx
volumes:
- /nginx_config/:/etc/nginx
- /nginx_html/<wordpress-website>:/var/www/html
ports:
- 80:80
- 443:443
networks:
- wordpress
php-fpm:
image: bitnami/php-fpm
volumes:
- /nginx_html/<wordpress-website>:/var/www/html
networks:
- wordpress
volumes:
mariadb_data:
nginx_config:
nginx_html:
networks:
wordpress:
NGINX Configuration Setup
First, initiate the Docker container in detached mode:
1
docker compose up -d
Then, to transfer the NGINX configuration files from within the container to your host’s /nginx_config
volume, execute:
1
docker run --rm -ti -v nginx_config:/data --entrypoint bash nginx -c 'cp -a /etc/nginx/. /data'
This command launches a transient, interactive container using the NGINX image. It binds the nginx_config
named volume to /data
inside this container and employs a custom entrypoint to run a bash shell command, which replicates the entire contents of /etc/nginx/
from inside the container to /data
on the mounted volume.
Should you need to direct the NGINX configuration files to a different host directory, adjust the volume mount (-v
) in the command accordingly. For instance, to place the files into /nginx_config/conf.d
on your host, utilize:
1
docker run --rm -ti -v /nginx_config/conf.d:/data --entrypoint bash nginx -c 'cp -a /etc/nginx/. /data'
Open and edit the default NGINX configuration file located at /nginx_config/conf.d/default.conf to the values below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sudo vi /nginx_config/conf.d/default.conf
server {
listen 80;
server_name <host-public-ip-address or DNS name, ie exmaple.com www.example.com>;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
root /var/www/html;
index index.php;
}
Create a new MariaDB database
First, ensure that the MariaDB MySQL client and bzip2 is installed on the host system.
1
2
sudo dnf install mariadb -y
sudo dnf install bzip2 -y
Make sure to you upload and unzip the exported & zipped database to the current directory on your host.
1
bunzip2 <db-backup-name>.bak.sql.bz2
On the Docker host, enter the Docker container’s mariadb mysql CLI using the password you added to the Docker Compose file. Verify the IP address of your MariaDB container. You can find it using:
1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name_or_id>
Connect to the MariaDB container using the IP address from the above command. Now, enter this command from the host to connect to the mariadb container:
1
mysql -h <mariadb-ip-address> -u root -p
We will then need to create a new database for wordpress, and run the source command to import the old WordPress database into our new database.
1
2
3
4
5
6
CREATE DATABASE wordpress;
CREATE USER '<wordpress_user>'@'localhost' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON <db_name>.* TO '<wordpress_user>'@'localhost';
USE wordpress;
source <db-backup-name>.bak.sql
EXIT;
Update DNS records
If you decided to move hosts, you will need to update the A or CNAME records to the public IP address of your new host, with your DNS provider like Namecheap.
All that’s left to do is run docker compose up and access the website in your web browser.
1
sudo docker compose up -d
Featured Tweet
Have you ever wondered how to migrate a WordPress website to Docker? Learn how in this detailed step-by-step tutorial.#wordpress #docker #homelab #sysadmin #MySQL #Linux #CentOS #RHEL #PHP #NGINXhttps://t.co/FqHvT4pzaS
— rcdevops (@rcdevops) March 22, 2024