← All articles
black flat screen computer monitor

Kopia: Fast, Encrypted Backups With a Modern Web UI

Infrastructure 2026-02-13 · 13 min read kopia backup snapshots encryption deduplication self-hosted disaster-recovery
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

You already know you need backups. The 3-2-1 rule has been hammered into every sysadmin's skull: three copies of your data, on two different media types, with one off-site. Ransomware, drive failures, accidental rm -rf commands, silent data corruption -- any one of these can wipe out years of irreplaceable data in seconds. The question isn't whether to back up, but which tool to trust with the job.

Photo by Joan Gamell on Unsplash

If you've looked at self-hosted backup tools, you've probably landed on BorgBackup or Restic. Both are excellent. But there's a third option that's been gaining serious traction: Kopia. It combines the content-addressable storage and encryption of Restic with the one thing both Borg and Restic lack -- a built-in web UI for managing snapshots, policies, and restores without touching the terminal.

Kopia backup tool logo

Kopia vs the Competition

Before diving into setup, here's how Kopia stacks up against the other major self-hosted backup tools.

Feature Kopia Restic BorgBackup Duplicati
Language Go Go Python/C C#/.NET
Interface CLI + Web UI CLI only CLI only Web UI only
Encryption AES-256-GCM or ChaCha20-Poly1305 AES-256-CTR + Poly1305 AES-256-CTR + HMAC-SHA256 AES-256
Deduplication Content-addressable, variable-size blocks Content-defined chunking Content-defined chunking Block-level
Compression zstd, gzip, pgzip, s2, deflate zstd (since 0.16) lz4, zstd, zlib, lzma Built-in (zip-based)
Cloud backends S3, B2, GCS, Azure, SFTP, rclone, WebDAV S3, B2, SFTP, rclone, REST SSH only (native) 20+ native
Multi-machine Built-in server mode Manual (REST server) Manual (SSH) Manual
Snapshot policies Per-directory, per-host, global Manual forget rules Manual prune rules Per-job via UI
Performance Fast, multi-threaded Fast, multi-threaded Fast, single-threaded Moderate
Windows support Yes Yes No Yes
Project age 2019 2015 2010 (as attic) 2008

When to choose Kopia

You want the power of Restic -- content-addressable storage, strong encryption, cloud-native backends -- but you also want a web interface for managing policies and monitoring snapshots. You're backing up multiple machines and want a central server that handles everything. You like granular snapshot policies that you can set per directory, per host, or globally without writing custom scripts.

When to choose Restic

You want the most battle-tested cloud backup tool with the largest community. You're comfortable with CLI-only workflows and already have monitoring wrappers in place. Restic's ecosystem of third-party tools (resticprofile, rustic, autorestic) is larger than Kopia's.

When to choose BorgBackup

You're backing up to a local NAS or another machine over SSH, you want the widest range of compression algorithms, and you run Linux exclusively. Borg's compression options are still the most flexible of any backup tool.

When to choose Duplicati

You want a GUI-first experience, need to back up to consumer cloud storage (Google Drive, OneDrive, Dropbox), or you're setting up backups for someone who won't touch a terminal. Duplicati has the most backend options, though it trades performance for accessibility.

Core Features

Before getting into the install, here's what makes Kopia interesting as a backup engine.

Content-addressable storage. Kopia splits your files into variable-size blocks, hashes each one, and stores only unique blocks. If you have the same file in three places, Kopia stores it once. If a 10 GB file changes by one byte, Kopia stores only the changed block, not the entire file again.

Client-side encryption. All data is encrypted before it leaves your machine. Kopia supports AES-256-GCM (hardware-accelerated on modern CPUs) and ChaCha20-Poly1305 (faster on machines without AES-NI). The repository password never leaves the client.

Deduplication across machines. When running Kopia in server mode, multiple machines back up to the same repository. Deduplication works across all of them. If three machines all have the same 500 MB log file, it's stored once.

Compression. Kopia compresses data before encryption using your choice of algorithm. The default is zstd, which offers a good balance of speed and ratio. You can configure compression per directory -- use aggressive compression for text-heavy directories and skip it for already-compressed media.

Built-in web UI. Kopia ships a web interface for browsing snapshots, configuring policies, monitoring backup status, and restoring files. It's not an afterthought bolted on with a separate project -- it's part of the core binary.

Snapshot policies. This is where Kopia really differentiates. You define retention, scheduling, compression, and error handling rules at multiple levels: global, per-host, per-user, or per-directory. Policies inherit and cascade, so you set sensible defaults globally and override them where needed.

Installing Kopia With Docker Compose

The simplest way to run Kopia as a backup server with the web UI is Docker Compose. This gives you a central server that you can point multiple machines at.

# docker-compose.yml
services:
  kopia:
    image: kopia/kopia:latest
    hostname: kopia-server
    restart: unless-stopped
    ports:
      - "51515:51515"    # Kopia server API + Web UI
    command:
      - server
      - start
      - --tls-generate-cert
      - --address=0.0.0.0:51515
      - --server-control-username=admin
      - --server-control-password=${KOPIA_ADMIN_PASSWORD}
    environment:
      KOPIA_PASSWORD: ${KOPIA_REPO_PASSWORD}
      TZ: America/Los_Angeles
    volumes:
      - kopia_config:/app/config
      - kopia_cache:/app/cache
      - kopia_logs:/app/logs
      - /mnt/backup/kopia-repo:/repository  # local repository storage
      # Mount directories you want to back up (read-only)
      - /home:/sources/home:ro
      - /var/lib/docker/volumes:/sources/docker-volumes:ro
      - /etc:/sources/etc:ro

volumes:
  kopia_config:
  kopia_cache:
  kopia_logs:

Create a .env file alongside your compose file:

KOPIA_ADMIN_PASSWORD=your-secure-admin-password
KOPIA_REPO_PASSWORD=your-repository-encryption-password

Important: The KOPIA_REPO_PASSWORD is your encryption key. If you lose it, your backups are unrecoverable. Store it in a password manager and print a physical copy.

Initialize the repository

Before starting the server, you need to create the repository:

docker compose run --rm kopia repository create filesystem \
  --path=/repository

Then start the server:

docker compose up -d

The web UI is at https://your-server:51515. Note the https -- Kopia generates a self-signed TLS certificate by default. Your browser will show a security warning; accept it or configure a reverse proxy with a proper certificate.

Log in with the admin username and password you set in the compose file.

Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.

Configuring Snapshots

Creating your first snapshot

From the web UI, navigate to Snapshots and click New Snapshot. Select a source directory (one of the paths you mounted into the container under /sources/). Kopia will run an initial snapshot immediately.

From the CLI inside the container:

docker compose exec kopia kopia snapshot create /sources/home
docker compose exec kopia kopia snapshot create /sources/docker-volumes
docker compose exec kopia kopia snapshot create /sources/etc

The first snapshot captures everything. Subsequent snapshots only process changed blocks and typically complete in seconds for datasets that haven't changed much.

Setting up snapshot policies

Policies control how often snapshots run, how long they're kept, what gets compressed, and what gets excluded. You can set them globally or per directory.

Global scheduling and retention:

docker compose exec kopia kopia policy set --global \
  --keep-latest 10 \
  --keep-hourly 24 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12 \
  --keep-annual 3 \
  --snapshot-interval 1h

This keeps hourly snapshots for a day, daily for a week, weekly for a month, monthly for a year, and annual snapshots for three years. Adjust to fit your needs and storage capacity.

Per-directory overrides:

# Keep Docker volumes longer -- they contain your service data
docker compose exec kopia kopia policy set /sources/docker-volumes \
  --keep-daily 14 \
  --keep-monthly 24

# Snapshot home directory less frequently
docker compose exec kopia kopia policy set /sources/home \
  --snapshot-interval 6h

Compression policy:

# Use zstd compression globally
docker compose exec kopia kopia policy set --global \
  --compression zstd

# Skip compression for media (already compressed)
docker compose exec kopia kopia policy set /sources/home/photos \
  --compression none

Exclude patterns:

docker compose exec kopia kopia policy set --global \
  --add-ignore "*.tmp" \
  --add-ignore "*.cache" \
  --add-ignore "node_modules/" \
  --add-ignore ".cache/" \
  --add-ignore "*.log"

All of this is also configurable through the web UI under Policies.

Cloud and Remote Backends

The Docker Compose example above uses local filesystem storage. For off-site backups, Kopia supports several remote backends.

Backblaze B2

docker compose run --rm kopia repository create b2 \
  --bucket=your-bucket-name \
  --key-id=your-key-id \
  --key=your-application-key

B2 costs $6/TB/month for storage and $0.01/GB for downloads. For a typical homelab with 500 GB of deduplicated backup data, that's about $3/month.

Amazon S3

docker compose run --rm kopia repository create s3 \
  --bucket=your-bucket-name \
  --region=us-east-1 \
  --access-key=your-access-key \
  --secret-access-key=your-secret-key

S3-compatible storage (MinIO, Wasabi, etc.)

docker compose run --rm kopia repository create s3 \
  --bucket=your-bucket-name \
  --endpoint=s3.wasabisys.com \
  --access-key=your-access-key \
  --secret-access-key=your-secret-key

SFTP

docker compose run --rm kopia repository create sftp \
  --path=/backup/kopia \
  --host=backup-server.example.com \
  --username=backup-user \
  --keyfile=/app/config/ssh-key

Mount your SSH key into the container if using key-based authentication.

Google Cloud Storage

docker compose run --rm kopia repository create gcs \
  --bucket=your-bucket-name \
  --credentials-file=/app/config/gcp-credentials.json

You can also use rclone as a backend, which opens up access to virtually any storage provider rclone supports (over 40).

Multi-Machine Backup

One of Kopia's strongest features is centralized multi-machine backup. The server you set up with Docker Compose can accept connections from Kopia clients running on other machines.

On the server

Add users for each machine that will connect:

docker compose exec kopia kopia server user add \
  backupuser@workstation \
  --user-password=client-password

On each client machine

Install Kopia (it's a single binary):

# Debian/Ubuntu
curl -s https://kopia.io/signing-key | sudo gpg --dearmor -o /etc/apt/keyrings/kopia-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kopia-keyring.gpg] http://packages.kopia.io/apt/ stable main" | sudo tee /etc/apt/sources.list.d/kopia.list
sudo apt update && sudo apt install kopia

# Fedora
sudo rpm --import https://kopia.io/signing-key
sudo dnf install kopia

# macOS
brew install kopia

# Windows
winget install kopia

Connect to the server:

kopia repository connect server \
  --url=https://your-server:51515 \
  --server-cert-fingerprint=FINGERPRINT \
  --override-username=backupuser \
  --override-hostname=workstation \
  --password=client-password

Get the certificate fingerprint from the server logs or the web UI.

Now create snapshots from the client:

kopia snapshot create /home/user
kopia snapshot create /etc

All clients share the same repository, so deduplication works across machines. If your laptop and desktop both have the same 2 GB VM image, it's stored once.

Pre/Post-Snapshot Hooks

Kopia can run commands before and after taking a snapshot. This is critical for databases -- you need to dump them before backing up the files.

# Create a pre-snapshot script
docker compose exec kopia kopia policy set /sources/docker-volumes \
  --before-snapshot-root-action="/app/config/pre-backup.sh"

Example pre-backup.sh:

#!/bin/bash
set -euo pipefail

# Dump PostgreSQL (Immich, Gitea, etc.)
docker exec immich_postgres pg_dumpall -U postgres > /sources/docker-volumes/db-dumps/postgres.sql

# Dump MariaDB
docker exec mariadb mariadb-dump --all-databases -u root -p"$MYSQL_ROOT_PASSWORD" > /sources/docker-volumes/db-dumps/mariadb.sql

echo "Database dumps complete"

Mount this script into the container and make sure it has execute permissions.

Retention Policies in Depth

Kopia's retention system is more flexible than most backup tools. Instead of a single set of keep rules, you define retention at multiple policy levels that cascade.

Policy hierarchy (most specific wins):

  1. Per-directory -- Rules for a specific path
  2. Per-user@host -- Rules for a specific machine
  3. Per-host -- Rules for all users on a machine
  4. Per-user -- Rules for a user across all machines
  5. Global -- Default rules for everything

This means you can set a conservative global policy (keep 7 daily, 4 weekly, 12 monthly) and then override it for specific paths that need more or fewer snapshots.

Example: Keep database dumps for two years, but only keep log directories for one week:

kopia policy set /sources/docker-volumes/db-dumps \
  --keep-monthly 24 \
  --keep-annual 5

kopia policy set /sources/home/logs \
  --keep-daily 7 \
  --keep-weekly 0 \
  --keep-monthly 0

Resource Requirements

Kopia is efficient, but requirements vary by workload.

Scenario RAM CPU Cache Disk
Single machine, < 500 GB data 512 MB 1 core 1-5 GB
Single machine, 1-5 TB data 1-2 GB 2 cores 5-20 GB
Server, 3-5 clients, < 2 TB each 2-4 GB 2-4 cores 20-50 GB
Server, 10+ clients, mixed workloads 4-8 GB 4+ cores 50-100 GB

Cache: Kopia maintains a local metadata cache to speed up operations. The cache size depends on the number of files and snapshots in your repository. For large repositories (millions of files), allocate generous cache space or operations will be slow.

Network: Initial backups transfer everything, so plan for that. Subsequent snapshots only transfer changed blocks. A homelab with 500 GB of data and typical daily churn (1-5 GB of changes) uses minimal bandwidth for incremental snapshots.

Restoring Files

From the web UI

Navigate to Snapshots, select the source directory, and browse the snapshot history. Click any snapshot to explore its file tree. Select files or directories and click Restore to download them or write them to a path on the server.

From the CLI

# List snapshots
kopia snapshot list

# Browse a specific snapshot
kopia ls <snapshot-id>

# Restore a full snapshot to a target directory
kopia restore <snapshot-id> /tmp/restore/

# Restore a specific file
kopia restore <snapshot-id>/path/to/file.txt /tmp/restored-file.txt

# Mount a snapshot as a filesystem (FUSE)
kopia mount <snapshot-id> /mnt/kopia-browse &

Disaster recovery

If your Kopia server is gone, you can restore from any machine with Kopia installed:

# Connect directly to the repository backend
kopia repository connect b2 \
  --bucket=your-bucket-name \
  --key-id=your-key-id \
  --key=your-application-key

# List all snapshots from all machines
kopia snapshot list --all

# Restore what you need
kopia restore <snapshot-id> /recovery/

You need the repository password and backend credentials. Store both somewhere safe outside the system you're backing up.

Honest Limitations

Kopia is a strong tool, but it has real trade-offs you should know about.

Younger project. Kopia's first stable release was in 2022. BorgBackup has been around since 2010, Restic since 2015. Kopia has fewer years of production battle-testing. It's stable enough for homelab and small business use, but large organizations tend to prefer Restic for its longer track record.

Smaller community. Restic has roughly 3x as many GitHub stars and a larger ecosystem of third-party tools, wrappers, and guides. When you hit a problem with Kopia, you're more likely to be the first person searching for it.

Web UI is functional, not polished. The web interface covers the essentials -- snapshots, policies, restores, server management. But it's utilitarian. Don't expect Duplicati's guided setup wizard or a dashboard full of charts. It gets the job done without hand-holding.

Documentation has gaps. The official docs cover common use cases well, but advanced configurations (complex policy hierarchies, rclone backend tuning, large-scale multi-tenant setups) sometimes require reading GitHub issues or source code.

Repository format changes. Kopia has made breaking repository format changes in the past during its pre-1.0 development. The format is stable now, but this history makes some people cautious. Always keep the ability to recreate your repository if needed.

No append-only mode for clients. Unlike Restic's append-only server mode, Kopia doesn't yet have a way to give clients write-only access that prevents them from deleting snapshots. If a compromised client connects to the server, it could potentially delete its own snapshots. The server access controls mitigate this, but it's not as hardened as Restic's append-only approach.

Practical Tips

Test restores regularly. A backup you've never restored is a backup you hope works. Schedule a monthly test: pick a random file, restore it, verify it's correct. Automate this if you can.

Monitor backup health. Kopia's kopia snapshot verify command checks data integrity. Run it weekly:

kopia snapshot verify --verify-files-percent=5

This verifies 5% of your backed-up files by re-reading them from the repository and checking hashes. Over time, you'll cover the full dataset.

Integrate with monitoring. Point your Uptime Kuma or Healthchecks.io instance at a script that runs after each snapshot:

#!/bin/bash
kopia snapshot create /sources/home && curl -fsS https://hc-ping.com/your-check-uuid

If the ping stops arriving, you know backups are failing.

Choose your backend wisely. For local backups (fast restores), use filesystem or NAS storage. For off-site (disaster recovery), use B2 or S3. Many people run both: a local repository for fast restores and a cloud repository for catastrophic failure. Kopia supports connecting to multiple repositories, though not simultaneously from the same client.

Size your cache. If Kopia operations feel slow (listing snapshots, browsing files), the cache is probably too small. Check cache usage:

kopia cache info

Increase it if needed:

kopia cache set --content-cache-size-mb=5000 --metadata-cache-size-mb=5000

Use maintenance wisely. Kopia runs automatic maintenance to clean up old data and optimize the repository. By default, quick maintenance runs hourly and full maintenance runs daily. If you're on metered storage, be aware that full maintenance rewrites some data blobs and temporarily increases storage usage.

Resources

The Bottom Line

Kopia sits in a sweet spot that didn't exist until recently: the performance and architecture of Restic, combined with a built-in web UI and the most flexible snapshot policy system of any open-source backup tool. Its server mode makes multi-machine backup straightforward instead of something you have to rig together with scripts.

The trade-off is maturity. Restic and BorgBackup have years more production use, larger communities, and deeper third-party ecosystems. If you're backing up critical business data and want the safest bet, Restic is still the default recommendation. But if you want a modern backup tool that you can manage through a browser, that handles multi-machine deduplication natively, and that's rapidly closing the maturity gap, Kopia is worth your attention. Set it up, automate it, test your restores, and you'll have a backup system that does its job without demanding constant maintenance.

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly