Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
DevOpsJune 21, 20264 min read

Docker data persistence: Backing up volumes with Restic and Cron

Docker data persistence is a critical skill. Learn how to automate reliable backups of your container volumes using Restic and Cron on Linux.

DockerResticBackupsLinuxDevOpsData PersistenceCI/CD
Shipping containers and cranes at Hamburg port showcasing global trade.

If you’ve ever accidentally wiped a production database container, you know the sinking feeling that follows. I learned this the hard way years ago when I deleted a volume directory thinking it was empty; I spent about four hours recovering data from a manual, out-of-date archive. Since then, I’ve moved away from "manual copies" to a consistent strategy for managing Docker data persistence using Restic.

Why Restic for Docker?

Restic is a modern, fast, and secure backup program. It handles deduplication and encryption natively, which is a massive upgrade over simple tarballs. When you're running apps on a single VPS—much like the setup I described in my guide on deploying a side project on a single cheap VPS reliably—you need a solution that doesn't bloat your system or require a complex Kubernetes cluster.

We first tried simple rsync scripts to a secondary drive. It worked until the disk filled up because we were storing full copies every night. Switching to Restic saved us roughly 60% in storage costs because it only stores the chunks that have changed.

Setting the Stage

Before you start, make sure you understand how your containers handle state. If you haven't mastered the basics of container lifecycles, I recommend reviewing Docker for app developers: A mental model that sticks to ensure your volumes are mounted correctly.

For this setup, we assume your Docker volumes live in the standard /var/lib/docker/volumes/ path.

  1. Install Restic: sudo apt install restic (or download the latest binary from their GitHub).
  2. Initialize your repository:
    Bash
    restic -r /srv/my-backups init
  3. Set your RESTIC_PASSWORD as an environment variable to allow non-interactive runs.

Automating with Cron

The most reliable way to handle data persistence backups is to keep the logic outside the container. If the container is crashing or stuck in a restart loop, your backup job should still be able to read the volume on the host filesystem.

Create a shell script at /usr/local/bin/backup-volumes.sh:

Bash
#!/bin/bash
export RESTIC_REPOSITORY="/srv/my-backups"
export RESTIC_PASSWORD="your-secure-password"

# Stop the containers if they write to disk constantly (Optional but recommended)
docker stop my-db-container

# Run the backup
restic backup /var/lib/docker/volumes/my-app-data/_data

# Start them back up
docker start my-db-container

# Prune old snapshots to save space
restic forget --keep-daily 7 --keep-weekly 4 --prune

Make it executable with chmod +x /usr/local/bin/backup-volumes.sh. Now, add it to your crontab (sudo crontab -e) to run at 3 AM daily:

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

Linux System Administration Best Practices

When dealing with Linux system administration, permissions are your biggest hurdle. The Restic process needs read access to the Docker volumes directory. I prefer running the cron job as root to avoid permission denied errors, but ensure the backup repository folder itself is owned by a restricted user if you’re concerned about security.

Also, don't ignore your logs. If your backup fails, you want to know before you actually need the data. I usually combine this with a simple health check script that verifies the last snapshot date and alerts me if it's older than 26 hours.

Dealing with "Live" Databases

The script above stops the container before backing up. This is the safest way to ensure data integrity for SQLite or PostgreSQL. If you cannot afford downtime, you have two options:

  1. Use a database-specific dump command (like pg_dump) inside a container and back up the resulting SQL file.
  2. Use a snapshot feature provided by your filesystem (like Btrfs or ZFS), but that's a topic for another day.

Frequently Asked Questions

Q: Can I backup to S3 instead of a local disk? Yes. Restic supports S3, Backblaze B2, and Azure Blob Storage natively. Just update your RESTIC_REPOSITORY string to point to your bucket (e.g., s3:s3.amazonaws.com/my-bucket-name).

Q: Does this handle container metadata? No. This only backs up the volume data. If you lose your container configuration, you'll need to re-run your docker-compose.yml or docker run commands. I keep my compose files in a Git repository to solve this.

Q: How do I restore? It's simple: restic -r /srv/my-backups restore latest --target /tmp/restore. You can then copy the data back to your volume directory.

Final Thoughts

I’m still tinkering with my pruning strategy. Sometimes I want to keep monthly backups for a year, but I worry about the repository size growing too quickly. For now, the keep-daily 7 --keep-weekly 4 logic is a good balance for my side projects.

Remember, a backup isn't a backup until you've successfully restored from it. Try doing a test restore once a quarter—you’ll be surprised at what you might have forgotten to include in your backup script.

Back to Blog

Similar Posts

Shipping containers and cranes at Hamburg port showcasing global trade.
DevOpsJune 21, 20264 min read

Docker Socket Activation: Zero-Downtime Hot-Swapping with Systemd

Docker socket activation with Systemd and Nginx lets you hot-swap containers without dropping connections. Learn this robust deployment engineering strategy.

Read more
Close-up of a green traffic light against a clear blue sky, symbolizing go and safety.
DevOps
June 21, 2026
4 min read

Blue-Green Deployment for VPS: Managing Traffic with Traefik

Master blue-green deployment on a single VPS using Docker Compose and Traefik. Achieve zero-downtime releases without the complexity of Kubernetes clusters.

Read more
A dramatic snow-covered mountain range beneath a dark, cloudy sky, showcasing rugged natural beauty.
DevOpsJune 21, 20264 min read

Ephemeral Linux Environments: Bootstrapping with Cloud-Init and Terraform

Ephemeral Linux environments let you test code in production-like conditions. Learn how to automate disposable servers using Cloud-Init and Terraform today.

Read more