Skip to content

Restic Backup Helper

A batteries-included Docker image built on top of restic/restic that wraps Restic in a cron-driven pipeline with optional Rclone replication, structured logs, mail and webhook notifications, Prometheus textfile metrics and operator-grade helpers for restoring, exporting and diagnosing.

Get started Docker Hub GitHub


What you get

  • Scheduled backup


    /bin/backup runs on BACKUP_CRON, with optional restic forget after each successful run via RESTIC_FORGET_ARGS.

    Backup worker

  • Integrity check & prune


    Decoupled CHECK_CRON and PRUNE_CRON so weekly verification and monthly compaction can run on their own cadence.

    Check & prune

  • Rclone replicate


    Push snapshots (or any source path) to a second remote using bisync, sync or copy, with credential masking in logs.

    Replicate

  • Operator restore


    /bin/restore — interactive on a TTY, flag-driven elsewhere — with safety rails, snapshot picker, mail/webhook notifications and a structured last-restore.json.

    Restore

  • Snapshot export


    /bin/snapshot-export packages a snapshot or subtree as a tar.gz archive for offline transfer or support handoff.

    Snapshot export

  • Forget preview


    /bin/forget-preview runs restic forget --dry-run with your configured retention policy, host/tag-scoped by default.

    Forget preview

  • Mount snapshot


    /bin/mount-snapshot exposes every matching snapshot read-only over FUSE under /fusemount, with safe target validation and a clean unmount on Ctrl+C / SIGTERM.

    Mount snapshot

  • Manual unlock


    /bin/unlock is the audited counterpart to RESTIC_AUTO_UNLOCK=OFF: explicit restic unlock with masked logging, last-unlock.json, pre-unlock / post-unlock hooks and the same mail / webhook plumbing as the cron-driven workers.

    Unlock

    Repository locks (concept guide)

  • Sources report


    /bin/sources-report is the pre-flight inventory: readability, type, file count and (optional) size for BACKUP_ROOT_DIR plus every --files-from / --exclude-file reference in RESTIC_JOB_ARGS. Catches missing mounts, stale --files-from entries and silently-empty exclude files before the next backup.

    Sources report

  • Init repo


    /bin/init-repo is the audited operator counterpart to the entrypoint auto-init probe: --dry-run reports the planned restic init command without mutation; without it a typed confirmation (init) or explicit --yes is required, so a container restart can never re-initialise a repository unattended.

    Init repo

  • Notify test


    /bin/notify-test sends clearly-labelled test mail and/or webhook payloads through the same helpers used by real workers, so you can validate msmtprc, MAILX_RCPT, WEBHOOK_URL, auth headers and timeout handling before waiting for a real failure.

    Notify test

  • Doctor diagnostics


    /bin/status (/bin/health-summary) gives a fast daily OK/WARN/FAIL summary from local state only. /bin/doctor prints a deeper read-only support bundle; /bin/cron-list answers "what will run and when?" with timezone, rendered crontab and schedule summary.

    Status Diagnostics

  • Observability


    Per-run JSON summary (/var/log/last-<job>.json), optional Prometheus textfile collector (restic_<job>.prom), webhooks and mail with informative subjects.

    JSON summaries

  • Security by default


    Inline credentials in repository URLs, replicate endpoints and webhook URLs are masked in logs and notifications. Secrets stay in RESTIC_PASSWORD_FILE / Docker secrets / orchestrator secrets.

    Security


Quick example

The shortest "it backs up every night and yells when it breaks" setup:

docker run -d \
  --name restic-backup-helper \
  -e RESTIC_REPOSITORY='s3:https://s3.amazonaws.com/my-bucket/restic' \
  -e RESTIC_PASSWORD_FILE=/run/secrets/restic_password \
  -e RESTIC_TAG=daily \
  -e BACKUP_CRON='0 2 * * *' \
  -e BACKUP_ROOT_DIR=/data \
  -v /srv/backup-src:/data:ro \
  -v restic-config:/config \
  marc0janssen/restic-backup-helper:latest
services:
  restic-backup:
    image: marc0janssen/restic-backup-helper:latest
    environment:
      RESTIC_REPOSITORY: s3:https://s3.amazonaws.com/my-bucket/restic
      RESTIC_PASSWORD_FILE: /run/secrets/restic_password
      RESTIC_TAG: daily
      BACKUP_CRON: "0 2 * * *"
      BACKUP_ROOT_DIR: /data
      MAILX_RCPT: ops@example.com
      MAILX_ON_ERROR: "ON"
      WEBHOOK_URL: https://hc-ping.com/00000000-0000-0000-0000-000000000000
    secrets:
      - restic_password
    volumes:
      - /srv/documents:/data:ro
      - ./config:/config:ro
      - backup-logs:/var/log
secrets:
  restic_password:
    file: ./restic.password
volumes:
  backup-logs:

See the full single-Pod manifest at examples/kubernetes/restic-backup-helper.yaml.

Pin your tags

Tagged images use the schema <helper-semver>-<restic-version>, e.g. 2.14.2-0.18.1. Pinning both protects you from surprise upstream behaviour changes. See Image tags.


How the documentation is organised

Tab Use it when…
Getting started You want to install, pull the right tag, or upgrade between minor/major versions.
Concepts You want to understand how cron, workers, locking and the filesystem layout fit together before changing config.
Configuration You're looking up an environment variable, hook name, mail/webhook flag or metric.
Workers You want to know exactly what /bin/backup, /bin/check, /bin/prune, /bin/replicate or /bin/rotate_log actually does.
Operations You are an operator running things by hand: restore, snapshot export, forget preview, diagnostics, troubleshooting.
Deployment You're writing the Compose / Kubernetes manifest, or hardening the orchestration layer.
Reference You're integrating with monitoring: JSON schema, Prometheus metric names, image tags, SBOM.

License & credits

Licensed under the MIT License.

Built on top of restic/restic and rclone; originally evolved from lobaro/restic-backup-docker.