Complete Tutorial: Building and Scheduling Docker Backup Script

Backing up Docker deployments is crucial. After an incident where I lost all my data due to a mishap with my Docker folder, I decided to create a backup script. This script ensures that all data is backed up, allowing for easy restoration whenever needed. The script also retains a defined number of backup copies and removes the rest.

Pre-requisite:

  • Docker containers must be deployed using docker-compose.

How the Script Works:

  1. Move one level down from the parent folder.
  2. Run “docker compose stop” to stop the container, and repeat this process for all Docker folders.
  3. Backup the parent folder with a filename formatted as the IP address and yymmddhhmmss.
  4. Retain only the specified number of backup copies and remove the oldest files.

Script Configuration:

  1. Define the parent folder of the Docker containers
    root_directory=”/var/docker”
  2. Specify where the backups will be stored:
    backup_folder="/var/lib/docker/backup"
  3. Set the number of backup copies to retain:
    codebackupCopies=5

Here’s the complete script:

#!/bin/bash
# Specify the root directory where you want to start the loop
root_directory="/var/docker"
backup_folder="/var/lib/docker/backup"
backupDate=$(date +'%y%m%d%H%M%S')
backupCopies=5
ipAddr=$(ip addr show $(ip route | awk '/default/ { print $5 }') | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1)
fileName="$ipAddr""_""docker_backup""_""$backupDate"".tar.gz"
# Loop through each subdirectory in the root directory to stop Docker container
find "$root_directory"  -maxdepth 1 -type d | while read -r directory; do
    echo "Processing directory: $directory"
    # Run your script here
    # For example, if your script is named "myscript.sh":
    # ./myscript.sh "$directory"
    # Add your script execution command here
    cd $directory

    if [ -f "docker-compose.yml" ]; then
       # If the file exists, call docker-compose down
       docker compose stop
#       echo "docker-compose.yml exists. Stopped docker-compose services."
    fi
    echo "Finished processing directory: $directory"
done
cd $backup_folder
tar -czvf $fileName /var/docker/
# Loop through each subdirectory in the root directory start docker container
find "$root_directory"  -maxdepth 1  -type d | while read -r directory; do
    echo "Processing directory: $directory"
    # Run your script here
    # For example, if your script is named "myscript.sh":
    # ./myscript.sh "$directory"
    # Add your script execution command here
    cd $directory

    if [ -f "docker-compose.yml" ]; then
       # If the file exists, call docker-compose down
       docker compose start
 #      echo "docker-compose.yml exists. Start docker-compose services."
    fi

    echo "Finished processing directory: $directory"
done

# Get a list of files sorted by modification time (newest first)
files=($(ls -t "$backup_folder"))

# Get the number of files to remove
files_to_remove=$((${#files[@]} - $backupCopies))

# If there are more than 5 files, remove the oldest ones
if [ "$files_to_remove" -gt 0 ]; then
    for ((i=$backupCopies; i<${#files[@]}; i++)); do
        file_to_remove="${backup_folder}/${files[$i]}"
        rm -f "$file_to_remove"
        echo "Removed file: $file_to_remove"
    done
else
    echo "There are $backupCopies or fewer files in the backup folder. No files removed."
fi


ls $backup_folder -l

Next, I create a crontab job daily executed at 00:00

sudo nano /etc/crontab

#enter below command at the last line of the file, save and exit. this cron job will run daily 00:00
0 0 0 0 0 root bash /var/scripts/backup-docker.sh

That’s all. thank you for reading

Leave a comment