How to Backup and Restore WordPress blog

We do have a blog

Running a self-hosted blog is not an easy task, but rewarding at the same time. It can teach many useful skills and techniques. In previous two posts “How to own a blog for FREE” Part 1 and Part 2 we deployed a blog to a cloud virtual machine, and run it in containers with docker-compose.

Here is a reminder of our blog architecture that looks like below.

Blog Architecture with Docker volumes

Time goes by, everything runs smoothly, we have multiple posts, but that strange feeling started creeping in… What if everything goes down? What if we lose database or WordPress container with all files? Well, that is a sign to start thinking about a backup!

Backup

For our setup we have two containers that do have permanent storage. One is obviously MySQL database. The other is WordPress. Why to backup WordPress? Because it stores many things on a file system, among which are source code files, configs, customizations and most importantly media uploads (images that we use in our blog posts). Therefore, we need to backup both containers, so we can restore entire blog at any point of time.

When we setup our blog we made crucial decision that will make our life so much easier. We store all MySQL and WordPress file in docker volumes.

What are Docker volumes?

Docker volumes are abstraction around file system that can be managed with Docker CLI. Among other advantages, volumes can be shared between containers and are easy to backup and restore.

pavel@pavel-UBUNTU:~$ sudo docker volume ls
DRIVER              VOLUME NAME
local               wordpressblog_db
local               wordpressblog_wordpress

Steps to backup

First, we would need to stop all running containers. The reason is simple, MySQL database or WordPress may still write data while we perform backup. That may render our backup corrupted, so it’s safer to stop all containers before doing backup. Of course, this will result in downtime, however backup shouldn’t take more than a minute, so in our case it’s acceptable.

#!/bin/bash

set -e

DOCKER="sudo docker"
DOCKER_COMPOSE="sudo docker-compose"
DOCKER_COMPOSE_FILE="/usr/local/etc/myblog/docker-compose.yaml"

# Stop containers
${DOCKER_COMPOSE} -f ${DOCKER_COMPOSE_FILE} down

Second step is to backup WordPress and MySQL files. To do that we run third container (in our case from debian:stretch-slim image) with the following options and commands.

  1. Mount WordPress and MySQL volumes one at a time.
  2. Mount local folder, in our case it is ~/backup.
  3. Archive WordPress and MySQL database folders into ~/backup folder.
# Create backup folder if not exists
mkdir -p ~/backup

# WordPress
$DOCKER run --rm \
    --mount source=myblog_wordpress,target=/var/www/html \
    -v ~/backup:/backup \
    debian:stretch-slim bash -c "cd /var/www/html && tar cvf /backup/myblog_wordpress.tar ."

#MySQL
$DOCKER run --rm \
    --mount source=myblog_db,target=/var/lib/mysql \
    -v ~/backup:/backup \
    debian:stretch-slim bash -c "cd /var/lib/mysql && tar cvf /backup/myblog_db.tar ."

Third step, we need to bring docker-compose up.

# Start containers
${DOCKER_COMPOSE} -f ${DOCKER_COMPOSE_FILE} up -d

And we all done. Our blog is available again and we have two backup files.

pavel@pavel-UBUNTU:~$ ls -l ~/backup/
total 310908
-rw-r--r-- 1 pavel pavel 232888320 Apr 26 06:18 myblog_db.tar
-rw-r--r-- 1 pavel pavel  85473280 Apr 26 06:18 myblog_wordpress.tar

Restore from a backup

If we have million backups but never tried to restore – we do not have backups!

Restore is similarly simple as backup. So first we need to stop containers. Reason is the same as for making a backup.

Second, we need to run third container, we are using debian:stretch-slim image again. This time we need to run the following commands.

  1. Mount MySQL and WordPress volumes one at a time.
  2. Mount a folder with backups, we have ~/backup.
  3. Delete all existing files from the WordPress and MySQL folders.
  4. Extract all files from backup archives into corresponding folders.
# WordPress
$DOCKER run --rm \
    --mount source=myblog_wordpress,target=/var/www/html \
    -v ~/backup:/backup \
    debian:stretch-slim bash -c "cd /var/www/html && rm -rf /var/www/html/* && tar -xvf /backup/myblog_wordpress.tar -C /var/www/html"

#MySQL
$DOCKER run --rm \
    --mount source=myblog_db,target=/var/lib/mysql \
    -v ~/backup:/backup \
    debian:stretch-slim \
    bash -c "cd /var/lib/mysql && rm -rf /var/lib/mysql/* && tar -xvf /backup/myblog_db.tar -C /var/lib/mysql"

Third step is to bring docker-compose up. And we should be all set!

Summary

Containerization helps a lot with replicating entire environment, which gives us tremendous advantage.

We can backup blog that runs in the cloud and restore from the backup locally, so we can try updates, new plugins or customizations without impacting our real blog running in the cloud! If we mess up locally, not a big deal, we can easily start over.

If machine gets lost in the cloud, we can bring up all containers on new machine and restore our blog from a backup with minimum disruption.

Backup blog often and try restore locally once in a while to make sure restore process works. Happy blogging!

Posts created 18

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top