How to Set Up Restic + S3-Compatible Storage for Fast, Encrypted Linux Backups (With Automation and Restore Testing)

Why Restic Is a Smart Backup Tool in 2026

If you want a modern backup system on Linux that is fast, encrypted by default, and easy to automate, restic is one of the most practical options available today. It creates deduplicated snapshots, supports incremental backups automatically, and works with many backends including local disks, SSH, and S3-compatible object storage (Amazon S3, Backblaze B2 S3 API, MinIO, Wasabi, and more). In this tutorial, you will set up restic with an S3-compatible bucket, run your first backup, verify integrity, and automate daily runs with systemd.

What You Need Before You Start

You will need a Linux machine (server or workstation), an S3-compatible bucket, and access credentials (Access Key ID and Secret Access Key). Make sure the bucket exists and that your account has permission to list, write, and delete objects. Also plan a secure place for a restic password (a file readable only by root is typical). If you are backing up a server, decide which paths to include and which to exclude (temporary folders, caches, and large build artifacts).

Step 1: Install Restic

On Ubuntu/Debian, you can install from the repo, but for newer features you may prefer the official binary release. First try the package manager:

Debian/Ubuntu: sudo apt update && sudo apt install -y restic

RHEL/Fedora: sudo dnf install -y restic

Confirm the version with restic version. If your distro version is old and you need a newer build, download the official release from restic’s GitHub and place it in /usr/local/bin.

Step 2: Create a Secure Password File

Restic encrypts the repository using a password. Store it in a root-owned file and lock down permissions:

sudo mkdir -p /etc/restic
sudo bash -c 'umask 077; printf "%s\n" "REPLACE_WITH_A_LONG_RANDOM_PASSWORD" > /etc/restic/repo.pass'
sudo chmod 600 /etc/restic/repo.pass

Use a long random password. If you lose it, you lose access to the backup data.

Step 3: Export S3 and Restic Environment Variables

Restic reads configuration from environment variables. For an S3-compatible provider, you will typically set the endpoint URL too (MinIO, Wasabi, or private S3 gateways). Create a config file you can reuse for scripts:

sudo bash -c 'cat > /etc/restic/env.sh <<EOF export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY" export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY" export RESTIC_PASSWORD_FILE="/etc/restic/repo.pass" export RESTIC_REPOSITORY="s3:https://s3.example.com/my-linux-backups" # Optional but common for S3-compatible services: export AWS_DEFAULT_REGION="us-east-1" EOF chmod 600 /etc/restic/env.sh'

Replace s3.example.com with your provider endpoint (or omit it for AWS), and use your bucket name in the repository path.

Step 4: Initialize the Backup Repository

Initialize the repo once. After that, all backups go into this encrypted repository:

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

If you see an error about permissions or endpoint connectivity, confirm that the endpoint URL is correct and that your credentials can write to the bucket.

Step 5: Run Your First Backup (With Sensible Exclusions)

A good first backup for a Linux server is often /etc, home directories, and important app data. Exclude caches and ephemeral content to reduce cost and time:

sudo bash -c 'source /etc/restic/env.sh; restic backup /etc /home \ --exclude "/home/*/.cache" \ --exclude "/home/*/.local/share/Trash" \ --exclude "/var/tmp" \ --exclude "/tmp"'

Restic will create a snapshot ID. That snapshot is an immutable point-in-time view you can list and restore later.

Step 6: Verify Backups and Test Restore

A backup that has never been verified is not a backup. Start by listing snapshots:

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

Then run an integrity check occasionally (especially after large backups):

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

Finally, do a small restore test to a temporary directory to confirm you can recover files:

sudo mkdir -p /root/restore-test
sudo bash -c 'source /etc/restic/env.sh; restic restore latest --target /root/restore-test --include "/etc/hostname"'

Open the restored file and confirm it matches the live system. This simple step catches password, permissions, and repository issues early.

Step 7: Automate Daily Backups with systemd

For reliable automation, systemd timers are cleaner than cron because they can track failures and integrate with logs. Create a backup script:

sudo bash -c 'cat > /usr/local/sbin/restic-backup.sh <<EOF #!/bin/bash set -euo pipefail source /etc/restic/env.sh restic backup /etc /home \ --exclude "/home/*/.cache" \ --exclude "/home/*/.local/share/Trash" \ --exclude "/tmp" --exclude "/var/tmp" # Keep policy: adjust to your needs and storage costs restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune EOF chmod 700 /usr/local/sbin/restic-backup.sh'

Now create a systemd service and timer:

sudo bash -c 'cat > /etc/systemd/system/restic-backup.service <<EOF [Unit] Description=Restic backup to S3 [Service] Type=oneshot ExecStart=/usr/local/sbin/restic-backup.sh EOF'

sudo bash -c 'cat > /etc/systemd/system/restic-backup.timer <<EOF [Unit] Description=Run restic backup daily [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target EOF'

Enable and start the timer:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
systemctl list-timers | grep restic

Troubleshooting Tips

If backups fail with S3 errors, double-check the endpoint URL, DNS, firewall rules, and bucket permissions. If you see slow performance, consider placing the repository in a region closer to your server, and avoid backing up huge temporary directories. If pruning takes too long, run it weekly instead of daily, or prune during low-traffic hours. Most importantly, schedule a recurring restore test (monthly is a good baseline) so you know recovery is possible when you actually need it.

Wrap-Up

With restic and S3-compatible storage, you get encrypted, deduplicated backups that scale from a single VPS to multiple servers. The setup is lightweight, the restore process is straightforward, and automation with systemd makes it dependable. Once this is working, the next advanced step is to add monitoring (alert on failed timers) and document your restore procedure so anyone on your team can recover data under pressure.

3.

How to Build a Self-Hosted S3-Compatible Backup Server with MinIO on Ubuntu (and Sync with rclone)

Cloud storage is convenient, but it is not always the best fit for large backups, privacy-focused environments, or labs where you want full control. A practical alternative is running your own S3-compatible object storage. In this tutorial, you will set up MinIO (an S3-compatible object storage server) on Ubuntu Server, secure it with a firewall, and then use rclone to sync backups to your new storage. The result is a modern backup target that works with many tools that already support Amazon S3.

What you will build

You will install MinIO as a system service, create a dedicated data directory, enable the MinIO web console, and harden access. Then you will configure rclone to push a local folder (your backups) into a bucket. This approach is useful for home labs, small businesses, and IT teams that want S3-style APIs without paying per-GB cloud fees.

Prerequisites

You need an Ubuntu Server (20.04/22.04/24.04 are fine), a user with sudo privileges, and at least one disk with enough space for your backup data. For best performance and safety, use a separate disk or mount point (for example, /mnt/minio). You should also know the server’s IP address and have SSH access.

Step 1: Create a MinIO user and storage path

First, create a dedicated system user and a directory for your objects. Keeping MinIO isolated makes permissions and troubleshooting much easier.

Commands:

sudo useradd --system --home /etc/minio --shell /sbin/nologin minio
sudo mkdir -p /mnt/minio
sudo chown -R minio:minio /mnt/minio

Step 2: Install the MinIO server binary

MinIO distributes a single binary. Download it, place it in /usr/local/bin, and make it executable.

cd /tmp
curl -LO https://dl.min.io/server/minio/release/linux-amd64/minio
sudo install minio /usr/local/bin/minio

Step 3: Create a configuration file

MinIO reads environment variables from a config file. Create /etc/default/minio and define your storage path, console port, and admin credentials. Use a strong password and store it safely.

sudo nano /etc/default/minio

Example configuration:

MINIO_VOLUMES="/mnt/minio"
MINIO_OPTS="--console-address :9001 --address :9000"
MINIO_ROOT_USER="minioadmin"
MINIO_ROOT_PASSWORD="CHANGE_THIS_TO_A_LONG_RANDOM_PASSWORD"

Then lock down permissions so regular users cannot read secrets.

sudo chown root:root /etc/default/minio
sudo chmod 600 /etc/default/minio

Step 4: Install a systemd service for MinIO

Running MinIO under systemd gives you automatic restarts and clean startup on boot.

sudo nano /etc/systemd/system/minio.service

Paste this service file:

[Unit]
Description=MinIO
After=network-online.target
Wants=network-online.target

[Service]
User=minio
Group=minio
EnvironmentFile=-/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TasksMax=infinity

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now minio
sudo systemctl status minio --no-pager

Step 5: Open firewall ports (or restrict them)

MinIO uses port 9000 for the S3 API and 9001 for the web console. If you use UFW, open only what you need. If this server is internal-only, restrict access to a management subnet.

sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp
sudo ufw enable

After this, the console should be reachable at http://SERVER_IP:9001. Log in with the root user and password you set earlier.

Step 6: Create a bucket for backups

Inside the MinIO console, create a bucket such as backups. Buckets are like top-level containers. You can also create separate buckets for endpoints like workstations, servers, or projects.

Step 7: Install and configure rclone on a client

Now install rclone on the machine that will send backups (this can be the same server or a different system). rclone supports S3-compatible endpoints, so it works well with MinIO.

sudo apt update
sudo apt install -y rclone

Run the configuration wizard:

rclone config

Create a new remote, choose s3, then set these key options:

Provider: Minio
Endpoint: http://SERVER_IP:9000
Access key ID / Secret access key: use credentials from MinIO (preferably a dedicated user, not the root account)
Region:

Step 8: Sync a local backup folder to MinIO

Assume your backups are stored in /srv/backups and your bucket is backups. Use sync to mirror the folder to object storage. If you want safer behavior, start with copy first.

rclone sync /srv/backups minio-remote:backups --progress --transfers 8

For ongoing operations, add logging and run it on a schedule with cron or a systemd timer. A simple cron example (daily at 01:30):

crontab -e

30 1 * * * rclone sync /srv/backups minio-remote:backups --log-file=/var/log/rclone-minio.log --log-level INFO

Troubleshooting tips

Console not reachable: verify MinIO is listening on ports 9000/9001 with ss -tulpn | grep 900 and confirm firewall rules.

Access denied from rclone: use a dedicated MinIO user and policy, confirm the access key/secret, and ensure the bucket name matches.

Slow performance: check disk throughput, avoid storing data on the OS disk, and consider using faster NICs or enabling multi-disk MinIO setups for scale.

Next steps

Once the basics work, consider adding HTTPS behind a reverse proxy (Nginx or Caddy), creating separate users and policies per team, and enabling bucket versioning for accidental deletion protection. With MinIO plus rclone, you get a flexible, modern backup target that speaks S3 while staying under your control.

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 ...