Jacar mascot — reading along A laptop whose eyes follow your cursor while you read.
Cómo Instalar

How to install restic for encrypted backups

How to install restic for encrypted backups

Actualizado: 2026-05-03

Backups are the discipline where most is learned the hard way and least written about until it hurts. After several incidents — backups that existed but weren’t restorable, destinations on the same server that burned, encryption that turned out to be off — I’ve ended up with a restic-based routine that covers the basics without pretending to be aerospace engineering. This post documents how to install it on Debian, set up an encrypted repository on S3-compatible storage, automate daily backups with systemd, and crucially, verify that restore works before you need it.

Key takeaways

  • restic encrypts everything client-side with AES-256; the storage operator sees nothing useful.
  • Variable-block deduplication makes incremental backups fast: only new blocks travel.
  • The repository password is as important as the data itself: if lost, recovery is impossible.
  • Weekly restore verification is not optional; a repository you’ve never run restore on is an illusion.
  • The systemd timer + service pair gives better observability than cron, with Prometheus metrics and absence alerts.

Why restic

Options in the open mature backup space are several:

  • restic — client-side encryption, native S3, stable repository format, no remote server state.
  • borg — excellent but requires a service listening at the destination.
  • duplicity — older; works with chained patch files that complicate partial restores.
  • kopia — modern but still rotating pieces in its ecosystem.

The reason I use restic in most cases is a combination of three properties: it writes to any S3-compatible repository without extra layers, it has a simple verifiable encryption model, and its repository format has been stable for years. restic encrypts everything client-side with AES-256 before sending. The storage operator sees nothing but sizes and opaque metadata. It deduplicates at the variable-block level so a modified file only transmits the changed blocks.

Installing on Debian 13

Installing on Debian is straightforward. The official repository package is usually a couple of versions behind, so for production I prefer installing from the project’s official signed binaries:

bash
VERSION=0.18.0
curl -LO "https://github.com/restic/restic/releases/download/v${VERSION}/restic_${VERSION}_linux_amd64.bz2"
curl -LO "https://github.com/restic/restic/releases/download/v${VERSION}/SHA256SUMS"
grep "restic_${VERSION}_linux_amd64.bz2" SHA256SUMS | sha256sum -c -
bunzip2 restic_${VERSION}_linux_amd64.bz2
sudo install -m 0755 restic_${VERSION}_linux_amd64 /usr/local/bin/restic

Alternatively use apt install restic and accept the repository version, which works for most cases. The practical difference is bug fixes and performance improvements in recent releases.

Setting up a repository on S3-compatible storage

restic works with many repository types: local directory, SFTP, S3, Backblaze B2, Azure, Google Cloud Storage. The case I cover here is a repository on an S3-compatible service, which is the pattern that best separates backup data from the protected server. Hetzner Object Storage, Backblaze B2, Wasabi, or an AWS bucket work well.

First, generate credentials with minimum permissions:

  • Only object creation, listing, and reading in the target bucket.
  • Delete permission isn’t required: restic manages its own lifecycle and deletions can be done with a separate credential to limit blast radius.

The password stored in /etc/restic-password is the only thing needed to decrypt the repository. Keeping it additionally in a secondary location off the server is a fundamental part of the strategy: lose the password and you lose the whole repository even if the data is still in the bucket. A password manager, a physical safe with the printed value, another server replicating it. The specific option matters less than having at least two independent copies.

First backup

The exclude file deserves care. Directories you shouldn’t include:

  • /tmp and anywhere with large caches or Unix sockets.
  • The container manager’s own data paths if you already cover their volumes.
  • Unencrypted sensitive files that shouldn’t travel to the repository even if restic encrypts them.

The first backup takes time because it transmits everything. Later ones are much faster because restic deduplicates against what’s already there: only new blocks travel. In my experience an incremental over a server with tens of gigabytes takes between thirty seconds and two minutes, dominated by file enumeration rather than network.

Automation with systemd

The pattern I use is a timer plus service pair, because it gives better observability than cron. The service:

  • Declares Type=oneshot and reads an EnvironmentFile=/etc/restic/restic.env with credentials.
  • Runs a script that performs the backup, applies forget with retention policy (last seven daily, four weekly, twelve monthly), and runs prune to free space.
  • Writes metrics to /var/lib/node-exporter/textfile/restic.prom with success, duration, and size.

The timer uses OnCalendar=*-*-* 02:00:00, RandomizedDelaySec=30m to avoid storms, and Persistent=true to recover missed backups if the server was off. Activate with systemctl enable --now restic-backup.timer.

The metrics are watched by alert rules warning if the backup fails or hasn’t run in more than 36 hours. The metric-absence alert type catches silent failures where the script doesn’t even get to write a result — the same principle applied in monitoring with Uptime Kuma for basic monitoring.

Restore verification

The part most often forgotten and the one that hurts most when needed. A repository you’ve never run restore on isn’t a backup, it’s an illusion. The routine I keep is weekly: a separate timer fires a script that picks a recent snapshot, extracts a known subset to a temp directory, compares against a reference, and reports the result. If verification fails, I get an immediate alert.

Besides the sample restore, once a week I run restic check --read-data-subset=5% which verifies integrity of a fraction of the repository. In six months I’ve caught two faults: one was an expired credential the script wasn’t reporting as error, another was a corrupted block the storage provider reprovisioned after a ticket. Without weekly verification neither would have been caught until disaster.

Conclusion

The reasonable minimum for a production server: restic installed from verified binaries, repository on an S3 provider independent from the server, password replicated off-server in at least two places, daily backup via systemd with retention policy, weekly sample restore, and alerts if any of this fails or stops reporting metrics. All of that takes an afternoon the first time and prevents the class of disaster that ends careers. Time spent cold is trivial compared to time saved when something goes wrong.

Frequently asked questions

Does restic encrypt backups automatically?

Yes. Restic encrypts all data on the client before sending it to the repository using AES-256 with Poly1305-AES authentication. The remote repository never receives plaintext data.

How do I schedule automatic backups with restic on Linux?

The simplest approach is a script calling restic backup and a systemd timer that runs it daily. Timers offer better error handling and logging than cron.

Does restic work with object storage like S3?

Yes. Restic natively supports AWS S3, Backblaze B2, Google Cloud Storage, Azure Blob, and any S3-compatible service like Hetzner Object Storage or MinIO.

Was this useful?
[Total: 13 · Average: 4.4]

Written by

CEO - Jacar Systems

Passionate about technology, cloud infrastructure and artificial intelligence. Writes about DevOps, AI, platforms and software from Madrid.