How to Set Up Automated Backups for Self-Hosted Services: A Complete Guide

Automated backups for self-hosted services require a backup engine like Borgmatic or UrBackup, a scheduler such as systemd timers or cron, and an off-site destination like rsync.net or Backblaze B2 to ensure data durability.

Self-hosting services places full responsibility for data protection on the administrator. The mikeroyal/Self-Hosting-Guide repository provides a curated catalogue of backup solutions and architectural patterns for securing VMs, containers, and application data. This guide explains how to implement automated backups for self-hosted services using containerized tools and native Linux scheduling systems as documented in the source.

Architectural Overview

The Self-Hosting-Guide outlines a five-layer architecture for backup pipelines in README.md#L2306-L2324. Each layer serves a distinct function in the automated backup workflow:

  • Source Layer: The actual data requiring protection, including Docker volumes at /var/lib/docker/volumes/, Home Assistant configurations, Proxmox VMs, and application databases.
  • Backup Engine: The tool performing deduplication, compression, and encryption. Options include Borgmatic for immutable archives, UrBackup for client-server models, Kopia for modern snapshotting, and BorgWarehouse for web-managed repositories.
  • Off-Site Storage: Remote destinations accessed via rclone or SSH, including rsync.net, Backblaze B2, Amazon S3, and Wasabi.
  • Scheduler: Automation triggers using systemd timers, cron, or Docker Compose restart policies to execute backups at defined intervals.
  • Verification & Retention: Integrity checks via borgmatic check commands and retention policies that prune archives older than configured thresholds.

Borgmatic Implementation

Borgmatic provides a containerized, configuration-driven approach to creating deduplicated, encrypted backups. It is the recommended solution for Docker-based home labs according to the guide.

Docker Compose Setup

Deploy Borgmatic as a persistent container with read-only access to host data:


# docker-compose.yml

version: "3.8"
services:
  borgmatic:
    image: borgmatic/borgmatic:latest
    container_name: borgmatic
    restart: unless-stopped
    volumes:
      - /homeassistant:/data/homeassistant:ro
      - /var/lib/docker/volumes:/data/docker_volumes:ro
      - ./borgmatic/config:/etc/borgmatic
      - ~/.ssh:/root/.ssh:ro
    environment:
      - BORG_PASSPHRASE=YOUR_PASSPHRASE
    entrypoint: ["borgmatic", "--verbosity", "2", "create", "--stats"]

Configuration File

Define repositories, source paths, and retention policies in borgmatic/config.yaml:

location:
  source_directories:
    - /data/homeassistant
    - /data/docker_volumes
    - /etc
  repository: ssh://user@backup.example.com/~/borg-repo
  encryption_passphrase: env:BORG_PASSPHRASE

retention:
  keep_daily: 7
  keep_weekly: 4
  keep_monthly: 6

Systemd Timer Automation

Create a systemd service and timer to trigger the container daily at 02:30:


# /etc/systemd/system/borgmatic.service

[Unit]
Description=Borgmatic backup container
After=docker.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker start -a borgmatic
ExecStop=/usr/bin/docker stop borgmatic

# /etc/systemd/system/borgmatic.timer

[Unit]
Description=Run Borgmatic backup nightly

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Enable the timer with:

systemctl enable --now borgmatic.timer

UrBackup Server Alternative

UrBackup offers a client-server architecture suitable for file-level and full-image backups of heterogeneous systems.

Deploy the server component via Docker:


# docker-compose.yml

version: "3.8"
services:
  urbackup:
    image: uroni/urbackup-server:latest
    container_name: urbackup
    ports:
      - "55414:55414"
    volumes:
      - ./urbackup/data:/var/urbackup
    restart: unless-stopped

Install the UrBackup client on each target machine and point it to the server IP. The client automatically handles incremental backups and disk imaging without manual scripting.

Home Assistant Automated Snapshots

For Home Assistant specifically, trigger programmatic snapshots via the REST API:

curl -X POST -H "Authorization: Bearer YOUR_LONG_LIVED_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"name":"auto-snapshot"}' \
     http://homeassistant.local:8123/api/hassio/addons/backup/backup

Off-Site Storage Integration

Push local archives to cloud providers using rclone. After the backup engine creates the archive, execute:

rclone copy /backup/auto-snapshot.tar remote:backups/homeassistant/

Configure rclone with rclone config to support Backblaze B2, Wasabi, or any S3-compatible endpoint. For Borgmatic, specify the remote repository URL directly in the configuration (e.g., s3://bucket-name/backup-repo) to push archives without intermediate storage.

Summary

  • Select a backup engine matched to your infrastructure: Borgmatic for containerized deduplication, UrBackup for mixed client-server environments, or Kopia for policy-driven snapshots.
  • Mount host volumes as read-only into backup containers to prevent accidental data corruption while maintaining access to Docker volumes and configuration files.
  • Automate execution using systemd timers or cron rather than manual invocation to ensure consistent backup schedules.
  • Verify integrity by running borgmatic check or equivalent verification commands on a nightly basis to detect repository corruption early.
  • Enforce retention policies that align with storage capacity and compliance requirements, typically keeping daily backups for one week, weekly for one month, and monthly for six months.

Frequently Asked Questions

What is the best backup tool for Docker volumes?

Borgmatic is the recommended solution for Docker volumes in the Self-Hosting-Guide because it handles deduplication, compression, and encryption while running as a container with direct access to the host's /var/lib/docker/volumes path. It creates immutable archives that can be pushed to remote repositories via SSH or rclone-supported cloud storage.

How often should automated backups run?

Daily backups are the standard recommendation for active self-hosted services, with critical databases or configuration files backing up multiple times per day. Configure your systemd timer or cron job with OnCalendar=*-*-* 02:30:00 to run during low-activity hours, and adjust frequency based on data change rates and acceptable Recovery Point Objective (RPO).

How do I secure backup repositories with encryption?

Store the encryption passphrase in environment variables such as BORG_PASSPHRASE rather than plaintext configuration files, and inject these via Docker secrets or systemd environment files. For remote repositories, use SSH keys mounted as read-only volumes or HTTPS endpoints with certificate validation to prevent man-in-the-middle attacks during transmission.

Can I use cloud storage providers with these backup tools?

Yes, Borgmatic supports direct integration with S3, B2, and other cloud storage via repository URLs like s3://bucket-name/path, while UrBackup and Kopia offer native cloud backends. Alternatively, use rclone as a post-backup transfer mechanism to copy local archives to Backblaze B2, Wasabi, or rsync.net without modifying the backup engine configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →