In the IT world, there is a brutal adage: people are divided into those who do backups, and those who will start doing them. However, simply “doing backups” is only half the battle. The real challenge is creating a system that is reliable, automated, encrypted, and cost-effective to maintain.
Today, I will show you how to build such an infrastructure by combining Kopia (a powerful backup client) with Garage S3 (a lightweight object server) running on TrueNAS SCALE. This combination allows you to create your own data “cloud” that works as efficiently as commercial solutions like AWS S3 or Backblaze, while remaining 100% under your control.
The Pillars of Our Solution
Before we dive into the configuration, it is worth understanding why we chose these specific tools:
- Kopia: A modern backup tool that supports deduplication (it never sends the same data twice), compression, and end-to-end encryption. Crucially, Kopia does not store files in their natural form; instead, it splits them into encrypted blocks (Content-Addressable Storage), making it extremely resilient to transmission errors.
- Garage S3: Written in Rust, this is a lightweight and distributed object server compatible with the S3 API. Unlike the heavy MinIO, Garage is designed to run on fewer resources while offering high performance and native support for distributed clusters.
- TrueNAS SCALE: As a NAS operating system, SCALE provides a stable base for Docker containers and secure data storage on the ZFS file system.

Pitfalls: What You Won’t Read in the Official Documentation
My journey to “green status” in Kopia was paved with errors that might discourage many an admin. Here is how I overcame them:
1. Port Wars: S3 API vs Web Server
In Garage, ports are strictly divided. By default, Garage uses:
- Port 3900 (in my case 30188): This is the actual S3 API. This is where Kopia sends
PUT,GET, andLISTcommands. - Port 3902 (in my case 30189): This is the Web Server, which is used exclusively for hosting static sites directly from buckets.
Attempting to connect Kopia to port 30189 resulted in a 404 Not Found error. Why? Because the Web Server does not understand data write commands. If you see a 404 error while trying to create a repository – check if you haven’t mixed up your ports.
2. “Malformed Authorization Header”: The Region Issue
Kopia was sending authorisation headers with the region set to us-east-1 or dc1. Garage rejected them with the error:
Authorization header malformed, unexpected scope.
It turned out that Garage is extremely strict regarding the so-called “Scope” in the V4 signature. The solution was to force an empty region (--region="") or to check the garage.toml file to see exactly what name was defined there (often simply garage).
Implementation Step-by-Step
Step 1: Preparing the Environment on Linux Mint
Install Kopia using the .deb package. If you plan on using the terminal (and you will need to!), it is worth preparing a binary symlink straight away. Kopia installed from the UI package hides its CLI binary deep within the /opt directory.
# Create a symlink so the 'kopia' command is available system-wide
sudo ln -s /opt/KopiaUI/resources/server/kopia /usr/local/bin/kopia
Step 2: Configuration on the Garage Side (TrueNAS)
Since the Garage image is often a distroless type (lacking a bash shell), we execute operations directly via docker exec:
# Create a bucket for the iMac backups
docker exec ix-garage-garage-1 /garage bucket create mint
# Grant permissions to the Access Key
docker exec ix-garage-garage-1 /garage bucket allow mint --read --write --key GK7c0b...
Step 3: Initialising the Repository (CLI is the Key to Success)
When the GUI doesn’t allow for custom parameters, the terminal comes to the rescue. Here is the command that finally “shook hands” with Garage:
export AWS_S3_ADDRESSING_STYLE=path
kopia repository create s3 \
--bucket=mint \
--endpoint=192.168.0.13:30188 \
--access-key=GK... \
--secret-access-key=... \
--region="" \
--disable-tls
The variable AWS_S3_ADDRESSING_STYLE=path is critical – it forces addressing of the type ip:port/bucket, instead of the AWS default bucket.ip:port, which IP addresses do not support.
Backup Hygiene: What to Ignore and How to Automate?
Ignore Rules
There is no point in sending rubbish to the server. In my configuration, I excluded:
.cache: Thousands of temporary browser files..rustup/.cargo: Rust documentation and binaries (which can be restored with a single command).Downloads: Usually just a temporary storage area.VirtualBox VMs: Massive disk files that are better backed up less frequently using a dedicated tool.
Automation
In Kopia-UI, I set the schedule to “Every hour”. To ensure the process always runs, I added Kopia-UI to the Startup Applications in Linux Mint:
Command: /opt/KopiaUI/kopia-ui %U
Additionally, I ticked the “Run Missed Snapshots on Startup” option. If the iMac was switched off overnight, Kopia will perform the missed backup immediately after the morning login.
Summary: Was It Worth It?
Absolutely. The combination of Kopia and Garage S3 gives me:
- Ransomware Resilience: Snapshots are read-only from the client’s perspective once created (if Object Lock is configured).
- Space Efficiency: Thanks to deduplication, my snapshots take up a fraction of the actual data size.
- Privacy: Data leaves my computer already encrypted with a key that TrueNAS doesn’t even know.
If you are looking for an alternative to commercial clouds, this duo is currently one of the best choices for any Linux and TrueNAS user.
What does your “emergency plan” look like? Do you use S3 at home, or do you stick with classic Rsync? Let me know in the comments!




Leave a Reply