Set Up Restic + S3-Compatible Storage for Secure, Automated Linux Backups

Why Restic Is a Smart Backup Choice in 2026

Backups are easy to postpone until the day you need them. Restic is a modern backup tool that helps you avoid that trap by making backups fast, encrypted by default, and storage-efficient through deduplication. It works especially well with S3-compatible object storage (such as MinIO, Wasabi, Backblaze B2 S3, Cloudflare R2 via S3 API, and many NAS appliances), giving you an offsite backup that is both resilient and scalable.

In this tutorial, you will install Restic on Linux, connect it to an S3-compatible bucket, create a secure backup policy, automate it with systemd, and verify that restores work. The steps focus on a practical, production-friendly setup you can run on a server or workstation.

Prerequisites

Before you start, you need: a Linux machine (Debian/Ubuntu, RHEL/Rocky/Alma, or similar), credentials for an S3-compatible bucket (access key, secret key, endpoint URL, and bucket name), and enough permissions to read the directories you want to back up. If you are backing up system paths like /etc and /var, you will likely run Restic as root.

Step 1: Install Restic

On Ubuntu/Debian, you can install Restic from the package manager:

sudo apt update && sudo apt install -y restic

On RHEL/Rocky/Alma, Restic is often available via EPEL:

sudo dnf install -y epel-release && sudo dnf install -y restic

After installation, confirm the version:

restic version

Step 2: Define Environment Variables for S3 Storage

Restic reads S3 credentials from environment variables. Create a root-only environment file so secrets are not exposed in shell history:

sudo install -m 0600 /dev/null /etc/restic.env

Edit the file:

sudo nano /etc/restic.env

Add the following (adjust values for your provider):

AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY

AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY

AWS_DEFAULT_REGION=us-east-1

RESTIC_REPOSITORY=s3:https://s3.example.com/my-restic-bucket

RESTIC_PASSWORD=Use-A-Long-Unique-Passphrase

If you are using a custom endpoint (common with MinIO and many S3-compatible services), the repository URL format is important: s3:https://ENDPOINT/BUCKET. Keep the password strong; it encrypts your data, and there is no recovery if you lose it.

Step 3: Initialize the Restic Repository

Load the environment and initialize the repository:

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic init'

This creates the repository structure in your bucket. If initialization fails, double-check your endpoint URL, bucket name, and credentials. Also ensure the bucket exists and the credentials have permission to list, put, and delete objects.

Step 4: Run Your First Backup

Start with a clear, high-value set of directories. For example, backing up system configuration and user data:

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic backup /etc /home --exclude /home/*/.cache'

Restic will scan files, upload only new chunks, and output a snapshot ID. The next backups are usually much faster thanks to deduplication.

Step 5: Verify Snapshots and Test a Restore

List snapshots to confirm your backup history:

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic snapshots'

To restore safely, do a test restore to a temporary directory:

sudo mkdir -p /restore-test

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic restore latest --target /restore-test'

Open a few restored files and confirm permissions and content. A backup you never tested is not a backup; it is a guess.

Step 6: Add Retention and Repository Maintenance

Without retention rules, storage can grow quietly. A common policy keeps daily backups for a week, weekly backups for a month, and monthly backups for a year:

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune'

Also schedule an integrity check occasionally (weekly or monthly):

sudo -E bash -c 'set -a; source /etc/restic.env; set +a; restic check'

Step 7: Automate Backups with systemd

Create a service unit that loads the environment file. Save this as /etc/systemd/system/restic-backup.service:

[Unit]

Description=Restic Backup

Wants=network-online.target

After=network-online.target

[Service]

Type=oneshot

EnvironmentFile=/etc/restic.env

ExecStart=/usr/bin/restic backup /etc /home --exclude /home/*/.cache

ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

[Install]

WantedBy=multi-user.target

Now create a timer at /etc/systemd/system/restic-backup.timer:

[Unit]

Description=Run Restic Backup Daily

[Timer]

OnCalendar=daily

Persistent=true

[Install]

WantedBy=timers.target

Enable and start the timer:

sudo systemctl daemon-reload

sudo systemctl enable --now restic-backup.timer

To confirm it will run, check timers and the last run logs:

systemctl list-timers --all | grep restic

journalctl -u restic-backup.service --no-pager -n 100

Common Troubleshooting Tips

If you see authentication errors, re-check the environment file permissions and values, and confirm your storage provider’s S3 endpoint URL. If backups are slow, review exclusions (caches and build directories can explode in size) and consider backing up database dumps instead of live database directories. If you are backing up a server over a flaky connection, Restic’s incremental design helps, but you should still schedule backups during quieter hours.

With Restic plus S3-compatible storage, you get encrypted offsite backups, predictable automation, and a restore process that is straightforward. Once your daily job is stable, the next best improvement is to document a full recovery runbook and test it quarterly.

Configure Linux Backups with Restic and S3-Compatible Storage (Ransomware-Resistant How-To)

Why Restic + Object Storage Is a Modern Backup Strategy

Traditional file copy backups are easy to set up, but they are also easy to destroy. If ransomware encrypts your server or a compromised account deletes local snapshots, a “backup” stored on the same machine is usually gone. A more resilient approach is to use encrypted, deduplicated backups pushed to remote object storage (S3-compatible services like MinIO, Wasabi, Backblaze B2 S3, or AWS S3). In this tutorial, you will configure Restic on Linux to back up important folders to an S3 bucket, verify restores, and automate everything with a systemd timer.

What You Need

You will need a Linux server (Ubuntu/Debian/RHEL-based), outbound HTTPS access to your object storage endpoint, and credentials for an S3-compatible bucket. It is strongly recommended to use a dedicated bucket (or dedicated prefix) per server. You should also decide which paths to back up (for example: /etc, /home, application config, and data directories) and which directories to exclude (cache, node_modules, temporary files, and large rebuildable artifacts).

Step 1: Install Restic

On Ubuntu or Debian, install Restic from the package manager:

sudo apt update && sudo apt install -y restic

On RHEL/CentOS/AlmaLinux/Rocky, Restic is commonly available via EPEL:

sudo dnf install -y epel-release && sudo dnf install -y restic

Step 2: Prepare S3 Environment Variables

Restic uses environment variables for S3 authentication. Create a protected file so you do not store secrets in shell history. This example uses an S3-compatible endpoint (change values to match your provider):

sudo install -m 600 -o root -g root /dev/null /etc/restic.env

Edit /etc/restic.env and add:

export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export RESTIC_PASSWORD="USE_A_LONG_UNIQUE_PASSPHRASE"
export RESTIC_REPOSITORY="s3:https://s3.example.com/your-bucket/your-hostname"
export AWS_DEFAULT_REGION="us-east-1"

If you are using AWS S3 itself, your repository line may look like:

export RESTIC_REPOSITORY="s3:s3.amazonaws.com/your-bucket/your-hostname"

Step 3: Initialize the Repository

Load the environment file and initialize the repo. The repository will be encrypted using the password you set:

sudo bash -c 'source /etc/restic.env && restic init'

If you see “created restic repository,” you are ready to back up. If you get TLS or endpoint errors, re-check the endpoint URL and whether your provider requires a specific region or hostname style.

Step 4: Run Your First Backup (with Practical Excludes)

Start with a focused set of folders. Backing up everything under / is rarely ideal because it includes virtual filesystems and caches. Create an excludes file:

sudo install -m 644 /dev/null /etc/restic-excludes.txt

Add common excludes (customize as needed):

/proc
/sys
/dev
/run
/tmp
/var/tmp
/var/cache
/var/log/journal

Run a backup of key paths:

sudo bash -c 'source /etc/restic.env && restic backup /etc /home /var/www --exclude-file /etc/restic-excludes.txt --tag daily'

Restic performs deduplication automatically, so future backups are usually fast and storage-efficient.

Step 5: Verify Snapshots and Test a Restore

A backup is only useful if you can restore it. List snapshots:

sudo bash -c 'source /etc/restic.env && restic snapshots'

To test restoring a single file or folder safely, restore into a temporary directory:

sudo mkdir -p /restore-test

sudo bash -c 'source /etc/restic.env && restic restore latest --target /restore-test --include /etc/ssh'

Confirm files are present, then remove the test directory when you are satisfied.

Step 6: Add Maintenance: Forget and Prune

Without retention rules, backups will grow forever. Restic separates “forget” (remove snapshot references) from “prune” (actually remove unneeded data). A common policy keeps daily backups for two weeks, weekly backups for two months, and monthly backups for a year:

sudo bash -c 'source /etc/restic.env && restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune'

Also schedule occasional integrity checks (for example weekly):

sudo bash -c 'source /etc/restic.env && restic check'

Step 7: Automate with systemd (Safer Than Cron)

Systemd timers provide better logging and predictable behavior. Create a script:

sudo install -m 700 /dev/null /usr/local/sbin/restic-backup.sh

Edit /usr/local/sbin/restic-backup.sh:

#!/bin/bash
set -euo pipefail
source /etc/restic.env
restic backup /etc /home /var/www --exclude-file /etc/restic-excludes.txt --tag daily
restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune

Create a service unit at /etc/systemd/system/restic-backup.service:

[Unit]
Description=Restic Backup to S3

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/restic-backup.sh

Create a timer at /etc/systemd/system/restic-backup.timer:

[Unit]
Description=Daily Restic Backup Timer

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the timer:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer

Check status and logs:

sudo systemctl list-timers | grep restic
sudo journalctl -u restic-backup.service --since today

Final Hardening Tips

For better ransomware resistance, use credentials with the minimum required permissions (write, list, and read for restores), and consider an object storage feature like bucket versioning or object lock if your provider supports it. Keep the Restic password in a secure secrets manager when possible, and document your restore steps so you can recover quickly during an incident. With encrypted offsite backups and regular restore tests, you move from “we have backups” to “we can reliably recover.”

Popular Posts

Install Ollama and Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install Ollama + Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install a Local AI Chatbot on Ubuntu 24.04 with Ollama and Open WebUI (Step-by-Step)

Trending Now

Recovering from Btrfs Boot Failures Using GUI Tools on Fedora

By the end of this guide the reader will be able to identify a Btrfs‑based Fedora installation, boot from a live USB, list and restore snapshots using the graphical utilities btrfs‑assistant and snapper, and verify that the system returns to a functional state without resorting to the command line. Understanding the Btrfs Layout Used by Fedora Fedora Workstation and Fedora KDE install the root filesystem as a single Btrfs partition that contains two default sub‑volumes. One sub‑volume holds the traditional “/” hierarchy, while the second is dedicated to /var/lib/machines . The latter exists to keep container images out of snapshot operations; it remains empty on systems that do not run virtual machines. Because Btrfs stores data in sub‑volumes rather than separate partitions, a snapshot captures the state of an entire sub‑volume at a point in time. The installer (Anaconda) automatically registers these sub‑volumes with the snapper service. Snapper maintains a series of read‑only ...