Build Your Own Encrypted S3 Backup with Restic and MinIO (Docker Compose, 2025 Guide)

If you want fast, encrypted, and deduplicated backups without paying for a public cloud, pairing Restic with MinIO is a powerful option. Restic handles client-side encryption and incremental backups; MinIO provides an S3-compatible object store you fully control. In this hands-on guide, you will deploy MinIO using Docker Compose, initialize a Restic repository, automate backups with a retention policy, and verify restores. The steps work on modern Linux distributions (Ubuntu/Debian/RHEL) and on any host that can run Docker.

Prerequisites

- A Linux server with at least 2 CPU cores, 4 GB RAM, and storage sized to your backup needs.
- Docker and Docker Compose installed.
- A shell user with sudo rights.
- Optional but recommended: a hostname and TLS if exposing MinIO beyond localhost.

Step 1 — Create a Docker Compose file for MinIO

We will run MinIO on ports 9000 (S3 API) and 9001 (web console). Use a strong root user and password. Put the credentials into a .env file so they are not hard-coded in the Compose file.

# .env
MINIO_ROOT_USER=minioadmin_change_me_now
MINIO_ROOT_PASSWORD=SuperStrong_Passw0rd_change_me
MINIO_DATA_PATH=./minio-data
# docker-compose.yml
services:
  minio:
    image: minio/minio:latest
    container_name: minio
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"   # S3 API
      - "9001:9001"   # Web Console
    environment:
      - MINIO_ROOT_USER=${MINIO_ROOT_USER}
      - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
    volumes:
      - ${MINIO_DATA_PATH}:/data
    restart: unless-stopped

Start MinIO:

docker compose up -d

Open the web console at http://<server-ip>:9001 and sign in with the root user credentials from the .env file.

Step 2 — Create a bucket and a dedicated access key

For clear separation, create a bucket named restic and generate a dedicated access key limited to that bucket.

Option A (Web Console):

- Storage → Create bucket → Name: restic.
- Identity → Service Accounts → Create access key → Scope: restrict to the restic bucket (read/write). Save the Access Key and Secret Key.

Option B (CLI, quick start):

# Uses MinIO Client without permanent install
docker run --rm --network host \
  -e MC_HOST_local="http://${MINIO_ROOT_USER}:${MINIO_ROOT_PASSWORD}@127.0.0.1:9000" \
  minio/mc mb local/restic

For production, prefer a limited service account rather than using the root keys in automation.

Step 3 — Initialize a Restic repository

Install Restic from your distribution or from the official releases. Then export environment variables for the repository URL and credentials. Replace placeholders with your actual keys.

export RESTIC_REPOSITORY="s3:http://127.0.0.1:9000/restic"
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export RESTIC_PASSWORD="Choose_A_Strong_Repo_Password"

Initialize the repository (first time only):

restic init

Restic encrypts data with the password you set, before uploading. Keep this password safe; without it, restores are impossible.

Step 4 — Create a backup script with retention

Let’s script a daily backup with sensible retention (7 daily, 4 weekly, 6 monthly) and basic integrity checks.

sudo tee /usr/local/bin/restic-backup.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

# Environment (consider moving to /etc/restic/.env and source it)
export RESTIC_REPOSITORY="s3:http://127.0.0.1:9000/restic"
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export RESTIC_PASSWORD="Choose_A_Strong_Repo_Password"

# What to back up
INCLUDE_DIRS=(
  "/etc"
  "/var/www"
  "/var/lib/docker/volumes/project_data/_data"
  "$HOME"
)

# Exclusions
EXCLUDES=( 
  "--exclude-file=/etc/restic-excludes.txt"
)

# Run backup
restic backup "${EXCLUDES[@]}" "${INCLUDE_DIRS[@]}"

# Retention and pruning
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Lightweight consistency check (5% of data)
restic check --read-data-subset=5%
EOF
sudo chmod +x /usr/local/bin/restic-backup.sh

Create a simple exclusions file to skip caches and temporary data:

sudo tee /etc/restic-excludes.txt >/dev/null <<'EOF'
/home/*/.cache
/var/cache
/var/tmp
*.iso
*.qcow2
node_modules
EOF

Schedule the backup with cron:

(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/restic-backup.sh >> /var/log/restic.log 2>&1") | crontab -

Tip: For long-running servers, a systemd timer is often more reliable than cron. Also consider moving credentials into a protected file (chmod 600) and sourcing it inside the script.

Step 5 — Test listing and restoring

Verify snapshots:

restic snapshots

Restore a file or directory to a safe location:

# Find a snapshot ID from 'restic snapshots'
restic restore latest --target "$HOME/restore-test" --include /etc/hosts

Always test a restore. A backup you cannot restore is not a backup.

Step 6 — Secure access and expose safely

- Use HTTPS for MinIO. Either terminate TLS directly in MinIO (via certificates at /data/.minio/certs) or put MinIO behind a reverse proxy like Caddy or Nginx with automatic Let’s Encrypt.
- If backing up from remote machines, prefer private networks (Tailscale/WireGuard) rather than exposing port 9000 to the internet.
- Set strong passwords and rotate access keys periodically.

Step 7 — Useful maintenance and troubleshooting

- Verify integrity periodically: restic check (run monthly with full read if you can).
- Remove stale locks: restic unlock if a job was interrupted.
- Monitor logs: tail -f /var/log/restic.log for failures or timeouts.
- Storage growth: run restic prune occasionally (already included with forget --prune) and review your exclude list.

Why this stack works in 2025

Restic remains one of the most efficient open-source backup tools thanks to encryption-by-default, deduplication, and built-in S3 support. MinIO provides a modern, high-performance, and S3-compatible backend you can run on-prem or at the edge. With Docker Compose, you can upgrade easily, keep state on mapped volumes, and move the stack between servers without changing your backup commands.

With the steps above, you now have a repeatable, scriptable, and secure backup workflow: data is encrypted before it leaves the host, stored in an S3 bucket you control, and cleaned up automatically with a clear retention policy. Don’t forget to document your RESTIC_PASSWORD location and your MinIO access keys, and test restores on a schedule.

How to Set Up Rclone for Secure Cloud File Synchronization on Linux

Introduction

Cloud storage is an essential part of modern workflows, allowing users to access files from anywhere and back up important data securely. However, managing multiple cloud services can be a challenge, especially on Linux systems. Rclone is a powerful command-line tool that simplifies the process of syncing files and directories to and from dozens of cloud storage providers. This tutorial will guide you through installing Rclone on Linux, configuring it for cloud synchronization, and automating your backups.

Step 1: Installing Rclone on Linux

To get started, you need to install Rclone. Most Linux distributions offer Rclone in their package repositories, but it's best to install the latest version directly from the official website.

Open your terminal and run the following command to download and install Rclone:

curl https://rclone.org/install.sh | sudo bash

After installation, verify the Rclone version:

rclone --version

You should see the installed version number, confirming that Rclone is ready for use.

Step 2: Configuring a Cloud Storage Remote

Rclone supports a wide range of cloud providers, including Google Drive, Dropbox, OneDrive, S3, and many more. To connect to a cloud service, you need to create a new "remote" configuration.

Run the configuration command:

rclone config

Follow the interactive prompts:

  • Type n to create a new remote.
  • Enter a name (e.g., mydrive).
  • Select your cloud provider from the list.
  • Follow the authentication steps, which may include opening a browser and logging in.
  • Once complete, save and exit the configuration tool.

Your cloud remote is now ready for syncing files between Linux and your chosen cloud provider.

Step 3: Syncing Files with Rclone

With your remote configured, you can now sync files. For example, to sync your local Documents folder with the root directory of your cloud drive:

rclone sync ~/Documents mydrive:/Documents

This command copies any new or changed files from your local folder to the cloud. To sync in the opposite direction, simply switch the source and destination.

You can also use the copy command to transfer files without deleting anything from the destination:

rclone copy ~/Pictures mydrive:/Pictures

Step 4: Automating Backups with Cron

To automate your backups, use cron to schedule regular sync operations. Edit your crontab with:

crontab -e

Add a line like the following to run a sync every day at 2 AM:

0 2 * * * rclone sync ~/Documents mydrive:/Documents

This ensures your files stay up-to-date without manual intervention.

Conclusion

Rclone is an invaluable tool for Linux users who want reliable, flexible, and secure cloud file synchronization. With its broad support for cloud providers and automation capabilities, you can safeguard your data and streamline your workflow. Experiment with Rclone's advanced features, such as encryption and bandwidth throttling, to further optimize your cloud backup strategy.

3.

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

Zenwalk 7.1 Brings Linux 7.1 Kernel, Flatpak, and Xfce 4.20 to Slackware‑Based ISOs

By the end of this article readers will understand the new components introduced in the latest Zenwalk ISOs, how those components interact with the underlying Slackware base, and what practical steps administrators should consider when adopting the updated release. Overview of the Zenwalk Update Zenwalk, a Slackware‑derived distribution, has released a refreshed set of installation images that incorporate three notable changes: the Linux 7.1 kernel, integration of Flatpak as a first‑class package source, and the inclusion of Xfce 4.20 as the default desktop environment. The update aligns Zenwalk with recent upstream developments while preserving its traditional emphasis on a lightweight, source‑centric philosophy. Technical Significance of the Linux 7.1 Kernel The move to the Linux 7.1 kernel introduces a range of driver updates, scheduler refinements, and security hardening that were not present in the previous Zenwalk releases. For system administrators, the kernel upgrade mean...