Marc Wäckerlin
Für eine libertäre Schweiz

Backup Docker Volume to Remote Server

May 25, 2017

Use rsync through SSH with private keys in a con job to backup docker volumes to another server. For this purpose, I provide two docker images, one to provide SSH access to volumes and the other to pull the backup from a remote server:

In this example, I show how to backup a wordpress installation that consists of two volumes, one for the database and one for the uploaded files.

The wordpress installation was setup as:

docker run -d --restart unless-stopped \
           --name example-mysql-volume \
           mysql \
           sleep infinity
docker run -d --restart unless-stopped \
           --name example-wordpress-volume \
           wordpress \
           sleep infinity
docker run -d --restart unless-stopped \
           --name example-mysql \
           --volumes-from example-mysql-volume \
           -e MYSQL_ROOT_PASSWORD=eex3eiqueK \
           mysql
docker run -d --restart unless-stopped \
           --name example \
           --volumes-from example-wordpress-volume \
           --link example-mysql:mysql \
           wordpress

So there are two volumes to backup: example-mysql-volume and example-wordpress-volume.

To configure an automated remote backup from a source server named source to a target server named target, prepare the following information:

  1. chose an unused port on source to provide SSH access, e.g.: 208
  2. find the pathes you need to backup, e.g.:
    docker inspect -f '{{ .Config.Volumes }}' \
           example-wordpress-volume \
           example-mysql-volume \
           | sed 's,map\[\(.*\):{}\],\1,'
    

    here, this results in:

    /var/www/html
    /var/lib/mysql
    

To setup the backup, you need the following steps

  1. On target, create a volume to store the backed up data:
    docker run -d --restart unless-stopped \
                  --name example-backup-volume \
                  mwaeckerlin/pull-backup \
                  sleep infinity
    
  2. On target, run the backup-pull container:
    docker run -d --restart unless-stopped \
                  --name example-backup-pull \
                  --volumes-from example-backup-volume \
                  -e 'REMOTE_HOST=source' \
                  -e 'REMOTE_PATH=/var/www/html /var/lib/mysql' \
                  -e 'PORT=208' \
                  mwaeckerlin/pull-backup; \
    docker logs -f example-backup-pull
    
  3. On target, get the generated SSH public key:
    Please append the following key (without the dashed-lines) to:
    host: source
    file: ~root/.ssh/authorized_keys
    -------------------------------------------------------------------------------------
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDRqgwgiK/KYjDSnaJQXL9Y6dUDiMxv9+9t5Ql7/g5/zaffJ2jAwiaKHFk7PrYOgr6dhXpfOW06YHfkZXMA/M49fOsqisI2C5YesVk8n51UNsFSzTOWeehU/XRdIou/BPaLX+AoiF/OUhyanFj1cxTj3860a6Unn5H7SxFWknW13wB+LL3vHoC5tuKmHW/DkavIFehLRGuItOcT9SJpzeDmOba5Ny/oSof2ilLVzJyHTPzZFjacMafJni8N0sKACuKAn+CqiI9nH/K6VJ2Xzc9yRE9djOozrTlDFOcB72mQxjHSx1MNu//fRWDPm0SSpdkoo5s3QNOcrsUVdTJS7YaEOeTf2hVfoqLNTLrS+rqRyQTh6AR+owF8XffmBfzzYpdSCZ96gLywkssoGRe11bHdni/Sqf0a7o8pyQ7XpMaokWPaQO/mpKcnlB3SETeu4PmAa96/msDU4uhut51WY/ib1w+yD6Smf3XhrPyYbHc22/B7fCFybi/7kIfY0nzx6OaKalo7rtoNcsO5tGy6ewvcQU8jMZ3wGZiRPArl53HCx/Rl+t6Jgqhl8icNYfijupUzN/DamcESRwIO8oNq19Cb9+sRKkKo1m/Us80BoZK9Dqd7RUp0freWMSSD2v1bcVb+4e3P4L5aK4h4nZr+u7CqAt94wyc4VbgB0BhfzFWs9w== root@c93541fd7d61
    -------------------------------------------------------------------------------------
    

    (it is one line, after copying it you can stop the log with ctrl+c)

  4. On source, start an ssh server and provide the SSH public key from target:
    docker run -d --restart unless stopped \
               --name example-backup-provider \
               -p 208:22/tcp \
               --volumes-from example-mysql-volume \
               --volumes-from example-wordpress-volume \
               -e 'SSHKEY=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAvAM7p+3XUaFoPirM/6sjFoJW8LcfhIeGXLs+0+5LQ+E5sFdEOtLYjQkDIC7CKAQQMhlZwwOrVp+sAge2w6OYyiABkVA87BaMGNFpjCI3jX3B5QuqD1OYC9/H/Bqzhl0YTGxSu/jN19cpLIx4RWR/i2Tq1kOEw8UH5tA3KI4WWY2Z0qcSFVZjnCtrSpQ6wR7tdbBB1LsLe5yG3PMS/qGumz+vz7RwUKUH/X34DHN/8k3YpFQKO8hy+o3yAXHZtfxxdjrbMJBjhhT67WohqlqIDENBmp5cddz7rjhpMT3fWC50Lf8ems88DTuDvRJ37VE9RqhHJNAJE3vW0veFRliwlewt6i8ju+IDOrlKIOxSOlUuMU9jbDYKkTL0r0rGIAZbbEKkBEvz1GY9fV2xAQTy8GVMgDNNZcQNbmOxGUuWkarUS2Rn1sl1uoPJs7UcC2/m/kr4CbZBfFCMQJv0sGV4coLa9sYI9Fd9MW9U0CSK9WGZ0PN6P+eHOhuuxBmkb3ovZRhbpO8VRaIHlvWYy9UR0msrUYYTR+bQq3338xogqREXYOy9oxSyeUQoJ2bo+Mfqr/1KeKafWtlyg1HjIr0RM4VkP55KxagQHfGM3ujzXBF7TZnwfY0nLWiC/C4S3yzkJHJO4PaktcdvP2rMTREh2fATEm5CsAeWpysfWYhB9Q== root@e2a584ab3de6' \
               mwaeckerlin/ssh
    

Note, if you want tobackup to more than one server, you can specify more than one public SSH key, just seperate them with a newline (enter-key).

Note, if the last step is done within minute after the secon step, then the initial backup, which is normally very slow, will be finished before the cron job is started. If you need more time than 60s, just add an option to the mwaeckerlin/pull-backup container, such as -e 'SLEEP=120' for two minutes delay.

comments title