Docker Volume Backup & Restore Scripts

Docker Volume Backup & Restore Scripts

A persistent docker volume retains the data for your container. This can be backed up and restored via scripts

Locate a volume for backup

  1. List your volumes

     docker volume ls
    

    I want to back up this one

     local     opc_postgres_data
    
  2. You can list the volume’s contents here

     docker run --rm -v opc_postgres_data:/data busybox ls -la /data
    
     total 64
     drwx------   19 999      999           4096 Dec 20 16:26 .
     drwxr-xr-x    1 root     root            18 Dec 20 16:28 ..
     -rw-------    1 999      999              3 Dec 20 16:22 PG_VERSION
     drwx------    6 999      999             46 Dec 20 16:22 base
     drwx------    2 999      999           4096 Dec 20 16:25 global
     drwx------    2 999      999              6 Dec 20 16:22 pg_commit_ts
     drwx------    2 999      999              6 Dec 20 16:22 pg_dynshmem
     -rw-------    1 999      999           5743 Dec 20 16:22 pg_hba.conf
    

Backing up

  1. Create a new file named volume-backup.sh

     nano volume-backup.sh
    
  2. Paste the following content and ctrl+x to save - changing the VOLUME_NAME

     #!/bin/bash
    
     # Volume to Backup
     VOLUME_NAME="opc_postgres_data"
    
     # Set the current date for the backup file
     BACKUP_DATE=$(date +"%Y%m%d_%H%M%S")
    
     # Define the backup directory
     BACKUP_DIR="/home/opc/backups"
    
     # Create a backup of the Docker container data
     docker run --rm -v $VOLUME_NAME:/data -v $BACKUP_DIR:/backup busybox sh -c "cd /data && tar czf /backup/${VOLUME_NAME}_backup_${BACKUP_DATE}.tar.gz ."
    
     echo "Backup completed: $BACKUP_DIR/${VOLUME_NAME}_backup_${BACKUP_DATE}.tar.gz"
    
  3. Make a backups folder

     mkdir backups
    
  4. Make the script executable

     chmod +x volume-backup.sh
    
  5. STRONGLY ADVISED: Stop your container before backup

  6. Run the backup script

     ./volume-backup.sh
    
  7. View the contents of the backup

     tar -tvf $BACKUP_DIR/$VOLUME_NAME_backup_$BACKUP_DATE.tar.gz
    
     drwx------ 999/999           0 2024-12-20 09:22 data/
     drwx------ 999/999           0 2024-12-19 15:29 data/pg_wal/
     drwx------ 999/999           0 2024-12-19 13:16 data/pg_wal/archive_status/
     -rw------- 999/999    16777216 2024-12-20 09:52 data/pg_wal/000000010000000000000001
     -rw------- 999/999    16777216 2024-12-19 15:29 data/pg_wal/000000010000000000000002
     drwx------ 999/999           0 2024-12-20 09:23 data/global/
    
  8. You can now restart your container

Restoring

  1. Make a file called volume-restore.sh

     nano volume-restore.sh
    
  2. Paste in the following Ctrl+x to save - changing the VOLUME_NAME and BACKUP_FILE

     #!/bin/bash
    
     # Volume to restore
     VOLUME_NAME="opc_postgres_data"
    
     # Backup file to restore from (replace with your actual backup file name)
     BACKUP_FILE="/home/opc/backups/opc_postgres_data_backup_20241220_164111.tar.gz"
    
     # Restore the Docker volume from the backup
     docker run --rm -v $VOLUME_NAME:/data -v $(dirname $BACKUP_FILE):/backup busybox sh -c "rm -rf /data/* /data/..?* /data/.[!.]*; tar xzf /backup/$(basename $BACKUP_FILE) -C /data"
    
     echo "Restore completed for volume: $VOLUME_NAME"
    
  3. Make the script executable

     chmod +x volume-restore.sh
    
  4. Run the script

     ./volume-restore.sh
    
  5. Check if it restored OK

     docker run --rm -v opc_postgres_data:/data busybox ls -la /data
    
     total 64
     drwx------   19 999      999           4096 Dec 20 16:26 .
     drwxr-xr-x    1 root     root            18 Dec 20 16:28 ..
     -rw-------    1 999      999              3 Dec 20 16:22 PG_VERSION
     drwx------    6 999      999             46 Dec 20 16:22 base
     drwx------    2 999      999           4096 Dec 20 16:25 global
     drwx------    2 999      999              6 Dec 20 16:22 pg_commit_ts
     drwx------    2 999      999              6 Dec 20 16:22 pg_dynshmem
     -rw-------    1 999      999           5743 Dec 20 16:22 pg_hba.conf
    

Testing

I added the the user added-after-backup to my volume managed by my postgresSQL container. Note: I already took a backup before this point.

I then…

  • Stop my containers (i.e my docker-compose)

  • Run the volume-restore.sh script

  • Start the containers

When its restored, the new user (and all changes since the backup) are gone

Schedule Daily Backups

Now lets hook this up to backup every day

  1. Edit crontab

      export EDITOR=nano; crontab -e
    
  2. Paste this on the last line to run it daily

      0 0 * * * /bin/bash /home/opc/volume-backup.sh
    
  3. CTRL+X to save the file and exit

  4. You’ll then get daily backups on the stroke of midnight

     -rw-r--r--. 1 root root 8602367 Dec 21 00:00 opc_postgres_data_backup_20241221_000001.tar.gz
    

ENJOY

What’s the picture? It’s The Majestic, Leeds, which caught fire 10 years ago.

Blog Credits: Avinash Bendigeri