In my development environment, I am running WordPress on docker containers, and I want a system to backup (and restore) both the DB and the WordPress data.

For this article, I assume you are familiar with docker and Linux bash concepts.

If you just want to backup a DB running on WordPress, you should check this article: http://www.asciiware.com/?p=1218.

Container based Approach

My local WordPress+DB installation is running on Docker, and I will use another docker container as a helper to backup and restore my blog.

aveltens/wordpress-backup

The aveltens/wordpress-backup is a docker container that connects to a wordpress backend and database, performs backups, and stores the archives on a folder in the host filesystem.

To understand how the aveltens container works, look at the above diagram and consider the main variables involved:

  • dev_backup: name of the container running the backups
  • dev_db: name of the container running the database
  • dev_wordpress: name of the container running wordpress
  • ~/backup/dev: path on the host where we place the backups

Plus, the backup container needs to the existing containers, so we need to consider also:

  • docker network: used by the containers for communication

Get a network name

In my case, wordpress and mysql containers are already running on the host. Indeed, I started the blog with a docker-compose command, that instantiated the two containers which now communicating through an own network automatically created by compose.

The backup container needs to connect to the others for the backup. As such container is not instantiated by the same docker-compose run, I need to get the name of the existing docker network and pass it to the backup container with the with the parameter --network=<NETWORK_NAME>.

To find the name of the network, just run docker network ls

Run the backup-container

To run the solution, we need to provide the details for connecting to the db to the aveltens container. So, create a file named backup.properties and copy inside the below content.

# connection to db
DB_NAME=wordpress
DB_USER=root
DB_PASSWORD=somewordpress
DB_PORT=3306

# docker network where wordpress and db are running
DOCKER_NET=docker-local-dev_default

# name of existing wordpress and db containers
WP_CONTAINER=docker-local-dev_wordpress_1
DB_CONTAINER=docker-local-dev_db_1

# name of the new container to perform backup
BACKUP_CONTAINER=dev_backup_1

# destination where the backup will be saved
BACKUP_TARGET=$(pwd)/backups

Then, you can source the properties file and start the container

source backup.properties && \
docker run \
  --rm \
  -e MYSQL_ENV_MYSQL_DATABASE=$DB_NAME \
  -e MYSQL_ENV_MYSQL_USER=$DB_USER \
  -e MYSQL_ENV_MYSQL_PASSWORD=$DB_PASSWORD \
  -e MYSQL_PORT_3306_TCP_PORT=DB_PORT \
  --net $DOCKER_NET \
  --name $BACKUP_CONTAINER \
  -v $BACKUP_TARGET:/backups \
  --volumes-from=$WP_CONTAINER \
  --link=$DB_CONTAINER:mysql \
  -d aveltens/wordpress-backup 

Now the backup container is up and running and we can perform backups and restores.

Note: the container is started with the --rm option, so it automatically removes the container when you stop it.

Backup

We can force a backup with the command docker exec <BACKUP_CONTAINER> backup . In this case, we reuse the existing properties. So the backup command will be

source backup.properties && \
docker exec $BACKUP_CONTAINER backup

After the first run, we can see the first backup stored in the ~/backup/dev folder.

Note: when running the container, the backups are created once a day, by default at 3 am. Each backup is named with its timestamp in the format yyyyMMdd, and if you force two backups on the same day, the most recent will overwrite the older one.

Note: If you get an error message saying it cannot link to images as it does not belong to the default network, you likely used a wrong network name. Looks again at the network name section.

Restore a backup

Similarly to the backup, we can restore a backup just by running a command like docker exec <BACKUP_CONTAINER> restore <DATE> , where date is in form yyyyMMdd and points to the name of a backup.

In this case, we reuse the existing properties. Below you can see an example of restore command.

source backup.properties && \
docker exec $BACKUP_CONTAINER backup restore 20190719

Stop (and remove) the container

As the container is started with the --rm flag, when you stop it, the container is also removed. Hence you can stop and clean just by executing the below command.

source backup.properties && \
docker stop $BACKUP_CONTAINER

Considerations

This is a simple solution to implement, and requires some advanced docker knowledge.

The disadvantages of the solution are: (1) we are spinning a container for the backup. (2) the backups are limited to one per day.

As of July 2019, this is the current solution I use to backup my local development environment.

References


0 Comments

Leave a Reply

Avatar placeholder

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