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_PASSWORDis 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:
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:
| Feature | Kopia | Restic |
|---|---|---|
| Web UI | ✅ Built-in | ❌ CLI only (third-party UIs exist) |
| Encryption | AES-256-GCM | AES-256-CTR + Poly1305 |
| Deduplication | Block-level, variable size | Block-level, variable size |
| Compression | ✅ zstd, gzip, pgzip, s2 | ✅ zstd (v0.16+) |
| Backends | S3, B2, GCS, Azure, SFTP, local, Rclone | S3, B2, GCS, Azure, SFTP, local, Rclone, REST |
| Snapshot policies | ✅ Built-in scheduling + retention | ❌ Needs external scheduler (cron) |
| Incremental | ✅ | ✅ |
| Mount snapshots | ✅ FUSE | ✅ FUSE |
| Community | Growing | Mature, large |
| Language | Go | Go |
| Docker image | Official | Community |
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.