Backups are the most neglected part of any self-hosting setup — until the day you need one. Kopia is a modern, open-source backup tool that makes encrypted, deduplicated, incremental backups surprisingly painless. If you’ve looked at Restic and wondered whether there’s something with a GUI, Kopia is the answer.

What is Kopia?

Kopia is a cross-platform backup tool that stores encrypted snapshots in a repository. It handles deduplication at the block level, compresses data, and supports a wide range of storage backends — local disk, SFTP, S3, Backblaze B2, Google Cloud Storage, Azure Blob, and more.

Why Kopia?

  • Built-in web UI: Manage snapshots, browse restores, and configure policies from a browser
  • Encryption by default: AES-256-GCM — your backups are encrypted before they leave the machine
  • Block-level deduplication: Only unique data blocks are stored, saving significant space
  • Incremental forever: After the first full snapshot, only changes are uploaded
  • Flexible backends: Local disk, NAS, S3-compatible, SFTP, cloud storage
  • Snapshot policies: Automated retention (keep X daily, Y weekly, Z monthly)
  • Cross-platform: Linux, macOS, Windows, Docker

Prerequisites

Before starting, you’ll need:

  • A Linux server (Ubuntu 22.04+ or Debian 12+ recommended)
  • Docker and Docker Compose installed
  • A storage backend (local directory, NAS mount, or S3-compatible bucket)
  • At least 1 GB of RAM (Kopia is lightweight but deduplication uses memory during snapshots)

Docker Compose Setup

Create a directory for Kopia:

mkdir -p ~/docker/kopia
cd ~/docker/kopia

Create the docker-compose.yml:

services:
  kopia:
    image: kopia/kopia:latest
    container_name: kopia
    restart: unless-stopped
    ports:
      - "51515:51515"
    command:
      - server
      - start
      - --insecure
      - --address=0.0.0.0:51515
      - --server-username=admin
      - --server-password=${KOPIA_PASSWORD}
    environment:
      - KOPIA_PASSWORD=${KOPIA_PASSWORD}
      - TZ=America/New_York
    volumes:
      - ./config:/app/config
      - ./cache:/app/cache
      - ./logs:/app/logs
      # Mount directories you want to back up
      - /home:/sources/home:ro
      - /opt/docker:/sources/docker:ro
      # Local backup repository (or use S3/SFTP instead)
      - /mnt/backups/kopia:/repository

Create the .env file:

KOPIA_PASSWORD=your-strong-repository-password-here

Important: The KOPIA_PASSWORD is used both for the web UI login and for encrypting your repository. Use a strong, unique password and store it somewhere safe — if you lose this password, your backups are unrecoverable.

Initializing the Repository

Before starting the server, you need to create a repository. The type depends on your storage backend.

Local or NAS Storage

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

S3-Compatible Storage (MinIO, Backblaze B2, Wasabi)

docker compose run --rm kopia repository create s3 \
  --bucket your-backup-bucket \
  --endpoint s3.us-west-001.backblazeb2.com \
  --access-key YOUR_KEY_ID \
  --secret-access-key YOUR_APP_KEY

SFTP (Remote Server)

docker compose run --rm kopia repository create sftp \
  --path /backups/kopia \
  --host backup-server.example.com \
  --username backupuser \
  --keyfile /app/config/ssh-key \
  --known-hosts /app/config/known_hosts

Once the repository is initialized, start the server:

docker compose up -d

Access the web UI at http://your-server:51515. Log in with admin and your KOPIA_PASSWORD.

Configuring Snapshot Policies

Kopia’s policy system controls what gets backed up, how often, and how long snapshots are retained.

Creating Your First Snapshot

From the web UI, click New Snapshot and enter the source path (e.g., /sources/home). Alternatively, use the CLI:

docker exec kopia kopia snapshot create /sources/home

Setting a Retention Policy

docker exec kopia kopia policy set /sources/home \
  --keep-latest 10 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12 \
  --keep-annual 3

This keeps:

  • The 10 most recent snapshots regardless of age
  • 7 daily snapshots
  • 4 weekly snapshots
  • 12 monthly snapshots
  • 3 annual snapshots

Scheduling Automatic Snapshots

docker exec kopia kopia policy set /sources/home \
  --snapshot-interval 6h

Or for more control, set specific times:

docker exec kopia kopia policy set /sources/home \
  --snapshot-time 02:00 \
  --snapshot-time 14:00

Excluding Files and Directories

docker exec kopia kopia policy set /sources/home \
  --add-ignore "node_modules" \
  --add-ignore ".cache" \
  --add-ignore "*.tmp" \
  --add-ignore ".local/share/Trash"

Setting Up Multiple Backup Sources

A typical self-hosting setup might back up several directories:

# Application data
docker exec kopia kopia snapshot create /sources/docker

# Set different policies per source
docker exec kopia kopia policy set /sources/docker \
  --keep-latest 5 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --snapshot-interval 4h

docker exec kopia kopia policy set /sources/home \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --snapshot-interval 12h

Restoring From Backups

Browse Snapshots in the Web UI

The Kopia web UI lets you browse any snapshot like a file manager. Navigate to a snapshot, select files or directories, and download them directly.

CLI Restore

List available snapshots:

docker exec kopia kopia snapshot list /sources/home

Restore a specific snapshot to a target directory:

docker exec kopia kopia restore <snapshot-id> /tmp/restore-target

Restore a single file:

docker exec kopia kopia restore <snapshot-id>/Documents/important.pdf /tmp/

Mount a Snapshot (Read-Only)

docker exec kopia kopia mount <snapshot-id> /mnt/snapshot &
ls /mnt/snapshot/

This is useful for browsing old snapshots without extracting everything.

Reverse Proxy with Caddy

If you want to access Kopia over HTTPS:

k}opiar.eyvoeurrsdeo_mparionx.ycokmop{ia:51515

Remove the --insecure flag from the Docker Compose command and configure TLS:

command:
  - server
  - start
  - --address=0.0.0.0:51515
  - --server-username=admin
  - --server-password=${KOPIA_PASSWORD}
  - --tls-generate-cert

Security note: If exposing Kopia to the internet, always use HTTPS and a strong password. Consider placing it behind an authentication proxy like Authelia.

Monitoring Backup Health

Check Repository Status

docker exec kopia kopia repository status

Verify Snapshot Integrity

docker exec kopia kopia snapshot verify --all

List All Snapshots

docker exec kopia kopia snapshot list --all

Get Repository Size

docker exec kopia kopia cache info
docker exec kopia kopia repository status

Kopia vs Restic: Head-to-Head

Both are excellent backup tools. Here’s how they compare:

FeatureKopiaRestic
Web UI✅ Built-in❌ CLI only (third-party UIs exist)
EncryptionAES-256-GCMAES-256-CTR + Poly1305
DeduplicationBlock-level, variable sizeBlock-level, variable size
Compression✅ zstd, gzip, pgzip, s2✅ zstd (v0.16+)
BackendsS3, B2, GCS, Azure, SFTP, local, RcloneS3, B2, GCS, Azure, SFTP, local, Rclone, REST
Snapshot policies✅ Built-in scheduling + retention❌ Needs external scheduler (cron)
Incremental
Mount snapshots✅ FUSE✅ FUSE
CommunityGrowingMature, large
LanguageGoGo
Docker imageOfficialCommunity

Choose Kopia if: You want a web UI, built-in scheduling, and an all-in-one solution. Great for self-hosters who prefer managing backups through a dashboard.

Choose Restic if: You’re comfortable with CLI, want a battle-tested tool with a huge community, or already have it integrated into scripts. Restic’s ecosystem of wrapper tools (resticprofile, autorestic, backrest) is more mature.

Honest take: Both deduplicate and encrypt. The real difference is workflow. Kopia is the “I want one tool that handles everything” choice. Restic is the Unix philosophy “do one thing well” choice that you compose with cron, scripts, and monitoring.

Troubleshooting

“repository not connected”

The repository needs to be created before starting the server:

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

If the repository exists but the server can’t connect, verify the password matches:

docker compose run --rm kopia repository connect filesystem --path /repository

Snapshots Are Slow

  • Check if deduplication cache is warming up (first few snapshots are slower)
  • Add exclusions for large, frequently-changing files (databases, logs, VMs)
  • Increase cache size: kopia cache set --content-cache-size-mb 1000

High Memory Usage During Snapshots

Kopia loads block indexes into memory. For large repositories:

docker exec kopia kopia policy set --global --snapshot-parallel 1

Permission Errors on Source Directories

Make sure source volumes are mounted with :ro (read-only is fine for backups) and the container user can read the files. If running rootless Docker, you may need to adjust file permissions.

Repository Maintenance

Run periodic maintenance to optimize the repository:

docker exec kopia kopia maintenance run --full

Kopia runs quick maintenance automatically, but a full run helps reclaim space from deleted snapshots.

Conclusion

Kopia fills a real gap in the self-hosting backup landscape: it’s the tool that makes backups accessible without sacrificing power. The web UI means you’ll actually check your backups (instead of hoping that cron job is still running), and the built-in scheduling eliminates a layer of scripting that trips up most setups.

Start with a local repository to learn the workflow, then graduate to an offsite S3 backend for true disaster recovery. The 3-2-1 rule still applies: three copies, two different media, one offsite. Kopia makes hitting that target a lot less painful.