Skip to content

felipe-heredia/backup-orchestrator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Backup Orchestrator

A lightweight backup daemon that schedules and runs restic jobs on a Linux server. It reads a YAML config, fires jobs on cron schedules, retries on failure, and handles periodic maintenance (pruning old snapshots, checking repository integrity). Runs as a systemd service.

How it works

The binary reads config.yaml on startup, registers every job with a 6-field cron scheduler, then sits in the background waiting. When a job fires, it acquires an exclusive file lock (so concurrent runs of the same job are impossible), calls restic backup, and retries up to the configured number of times if something goes wrong. A separate maintenance job runs on its own schedule and calls restic forget --prune and restic check.

All output from restic is streamed line-by-line to a structured log file.

config.yaml
  └── scheduler (robfig/cron)
    ├── job: restic backup <path>   ← retries, file lock
    ├── job: restic backup <path>   ← retries, file lock
    └── maintenance: forget + check

Tech stack

Language Go 1.26
Scheduler robfig/cron v3
Backup engine restic (external binary)
Remote storage Backblaze B2 (or any restic backend)
Logging log/slog (structured text)
Process locking syscall.Flock
Service manager systemd

Prerequisites

  • Go 1.26+
  • restic installed
  • A restic repository already initialized

Configuration

config/config.yaml

version: 3

restic:
  binary: "/usr/bin/restic" # path to the restic binary
  repository: "b2:bucket:path" # restic repository URL

logging:
  level: "info" # debug | info | warn | error
  max_size_mb: 1 # optional, default 1
  max_backups: 3 # optional, default 3

retention:
  keep_daily: 7
  keep_weekly: 4
  keep_monthly: 6

maintenance:
  schedule: "0 50 4 * * *" # runs at 04:50 every day
  forget: true # run restic forget --prune
  check: true # run restic check

jobs:
  - name: "my-backup"
    type: "directory"
    schedule: "0 0 3 * * *" # runs at 03:00 every day
    retry:
      max_attempts: 2
      delay: "1m"
    tags: ["my-tag"]
    directory:
      path: "/data/my-dir"
      excludes: ["tmp", "cache"]

Schedules use 6-field cron format: second minute hour day-of-month month day-of-week.

config/.env

RESTIC_REPOSITORY="b2:bucket:path"
RESTIC_PASSWORD="restic-repo-password"
B2_ACCOUNT_ID="backblaze-account-id"
B2_ACCOUNT_KEY="backblaze-application-key"
HOME="/home/username"

Local development

git clone https://github.com/felipe-heredia/backup-orchestrator

cd backup-orchestrator

# Create required runtime directories
make dev-setup

# Create your secrets file
cp config/.env.example config/.env

# edit config/.env with real credentials
# Validate config and exit
go run ./cmd/orchestrator --validate

# Run a single job immediately without writing anything
go run ./cmd/orchestrator --dry-run --run-now "my-backup"

# Run the daemon
go run ./cmd/orchestrator

Production (systemd)

# 1. Make sure config/.env exists with real credentials

# 2. Build and install (copies binary, config, and service file)
make install

# 3. Start it
systemctl start backup-orchestrator
systemctl status backup-orchestrator

# Follow the logs
journalctl -u backup-orchestrator -f

# Uninstall
make uninstall

make install copies the binary to /usr/local/bin, config files to /etc/backup-orchestrator/, and enables the systemd unit. Edit config/backup-orchestrator.service to change the user, paths, or security settings before installing.

CLI flags

Flag Default Description
--config config/config.yaml Path to the YAML config file
--env-file config/.env Path to the secrets file
--log-file logs/backup-orchestrator.log Where to write logs
--lock-dir backup-orchestrator.lock/ Directory for job lock files
--validate false Validate config and exit
--dry-run false Pass --dry-run to restic (no writes)
--run-now "" Run a named job immediately and exit

About

A lightweight backup deamon for my homelab

Resources

Stars

Watchers

Forks

Contributors