Marcio Cunha

How to backup Docker volumes using shell scripts and cron

Learn how to create automated cron routines to compress and export persistent Docker container data without stopping running services.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • Docker volumes store vital files that require constant protection against physical failures and data corruption.
  • The tar utility compresses the data directory into a packaged archive to save storage space.
  • The cron scheduler runs scripts autonomously at predetermined times without human intervention.
  • Exporting data without shutting down the container ensures high availability for critical production workloads.
  • Keeping external copies of backups protects the server against primary hardware disasters.

Why automate Docker volume backups?

Managing persistent data in containerized environments requires strict operational discipline. When we use Docker to run databases, file servers, or productivity tools like Obsidian via Git on cron, all the important state of the application resides in local or mapped volumes. If the hard drive fails or a command accidentally deletes the files, the loss can be irreversible. In practice, this means relying solely on the native resilience of containers is far too risky for any modern infrastructure.

The main advantage of creating a custom backup routine using shell scripts is total flexibility. Unlike closed commercial software, a shell script allows you to decide precisely which folders to copy, what compression format to use, and to which remote server or cloud to send the generated files. Furthermore, this approach integrates seamlessly with robust automation tools and the broader ecosystem of container management and kernel resource handling, keeping complete control in the hands of the responsible engineer.

How persistent data works in Docker

To understand backups, we first need to comprehend where Docker stores its data. Containers are ephemeral, meaning everything generated inside their internal file system disappears as soon as the container is destroyed. To prevent this loss, we use named volumes or bind mounts, which are folders on the host operating system connected directly to the container's internal world.

In practice, Docker stores these volumes in a protected host directory, usually located in /var/lib/docker/volumes. Accessing this folder directly requires administrator privileges and can cause permission issues if files are modified incorrectly while the service is running. This is precisely why creating a centralized script that reads these paths and generates compressed archives is the cleanest and safest strategy to keep your homelab or production server safe from unforeseen events.

Creating the shell script to compress and export

The heart of our backup routine is a simple script written in Bash. It must locate the volume directory, package the files using native Linux utilities, and save the result in a dedicated backup directory. To ensure the process occurs without human error, we can structure the steps into an executable file that handles date variables and the cleanup of old files.

Below is a functional example script that you can adapt to your environment. It creates a compressed archive with a timestamp, making chronological identification easy during an emergency restore.

#!/bin/bash
BACKUP_DIR="/mnt/backups/docker"
SOURCE_VOL="/var/lib/docker/volumes/my_volume/_data"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="backup_volume_$DATE.tar.gz"

mkdir -p $BACKUP_DIR

tar -czf $BACKUP_DIR/$FILENAME $SOURCE_VOL

find $BACKUP_DIR -type f -mtime +7 -name "*.tar.gz" -exec rm {} \;

In this code, the DATE variable ensures unique names for each generated file, while the find command locates and removes files older than seven days, preventing the server disk from filling up with unnecessary old versions. Just like optimizing CI/CD pipelines that use caching to accelerate processes, efficient disk space management is a fundamental pillar for long-term stability.

Executing backups without shutting down services

One of the biggest concerns when creating backup routines in production environments is service interruption. After all, if the database or web application goes offline every time the script runs, the user experience will be compromised. The good news is that the tar utility can read volume files at runtime without needing to stop the container, although there is a slight risk of inconsistency if a write occurs at the exact millisecond the file is being read.

For the vast majority of small and medium-sized applications, this hot-read approach works flawlessly. If you use heavy relational databases, the engineering recommendation is to execute an internal trigger command, such as a database dump inside the volume, before compressing the directory. This ensures that data is consistent at the exact moment the compressed archive is generated, uniting high availability with absolute information integrity.

Automating the routine with the Cron scheduler

With the script tested and working in isolation, the next logical step is to automate its execution so you do not have to remember to run it manually every day. Cron is the standard Linux task scheduler, responsible for triggering commands and scripts at specific times and frequencies based on simple mathematical expressions.

To configure the schedule, open the administrator task editor by typing the corresponding command in the terminal. The example below shows how to configure the script to run every day at midnight:

crontab -e

0 0 * * * /usr/local/bin/docker-backup.sh >> /var/log/docker-backup.log 2>&1

This line tells the operating system to execute the script at minute zero of hour zero every day, recording both successful outputs and any potential errors in a dedicated log file. Periodically monitoring these logs is an excellent practice to ensure the storage system remains healthy and no silent failures go unnoticed by the support team.

Validating and restoring data in case of failure

Creating backups and never testing the restoration is equivalent to having no backup at all. When the worst happens and the main server suffers irreparable damage, you need to know exactly how to reverse the process and get the application up and running in the shortest possible time. The restoration procedure involves extracting the compressed archive back into the Docker volumes directory and restarting the corresponding containers.

To ensure the archive is not corrupted, it is recommended to perform periodic tests in a staging environment or on a secondary machine. Validating the integrity of compressed files through checksums and simulating disaster scenarios ensures that when a real emergency occurs, the technical team can act with absolute confidence and agility.

Final considerations

Automating Docker volume backups using shell scripts is an essential skill for anyone managing servers, homelabs, or cloud infrastructures. By combining the power of the tar command with the simplicity of the cron scheduler, you build a solid safety net independent of expensive proprietary solutions. Keeping this routine active and tested regularly guarantees the peace of mind needed to focus on developing new features and evolving your projects.