Note: These are notes from my own setup, not a definitive reference. I wrote them down as I went so I’d have something to follow if I ever have to rebuild this from scratch, not as verified documentation. Kopia’s flags and behavior may have moved on since I wrote this. If something doesn’t match what you see, check Kopia’s own docs for the current version.

Kopia is an open-source, encrypted, deduplicating backup tool, the kind of thing you run instead of paying for Backblaze’s app or piecing together rsync and a prayer. It has a client-server mode: a repository server holds the actual backup data, and KopiaUI runs on your desktop as a client that connects to it.

Running that server in Docker on Unraid works fine right up until the container restarts for an update. Then KopiaUI on the desktop refuses to reconnect, with no error that makes sense at a glance, just a fingerprint mismatch.

Two things cause this and they stack. First, Unraid’s Kopia template ships with --insecure in its Post Arguments. That’s fine for poking at the web UI, and completely useless for KopiaUI, because Kopia’s client-server protocol is gRPC and gRPC requires TLS. No amount of --insecure gets you around that. You are going HTTPS whether you planned to or not. Second, once you’re on HTTPS, that self-signed cert has to live somewhere that survives the container being recreated. Put it anywhere else and every image update hands KopiaUI a brand-new fingerprint.

Here’s the fix, plus the other rough edges in getting KopiaUI talking to a Kopia server running in Docker.

Before that: Docker isn’t your only option here. Kopia gives you two ways to connect KopiaUI to storage on Unraid, and it’s worth knowing both exist before you commit to the more involved one.

Option A: Point KopiaUI at a Network Share

No Docker container, no repository server, no htpasswd file or TLS cert to babysit. Install KopiaUI on the desktop and connect it straight to a repository sitting on an SMB share on Unraid. For one desktop backing up to a NAS you trust, that’s genuinely less to set up, and it’s a legitimate way to run Kopia long-term, not just a shortcut for testing.

What it costs you: the client needs the actual share credentials, not just a login to a Kopia server, so anything that can back up can also read, write, and delete the whole repository. There’s no per-user separation if more than one person or machine touches it. Maintenance (garbage collection) needs an owner, and whichever machine happens to be connected when it’s due isn’t a reliable one if that machine is a laptop that sleeps most of the day. And the connection is SMB: mapped drives drop after sleep, fight you over cached credentials, and don’t survive leaving the LAN without a VPN.

None of that costs you speed. Chunking, hashing, compression, and encryption all happen client-side either way, direct-to-share or through a server.

Option B: Run a Repository Server (What This Post Covers)

The Docker container on Unraid runs as the repository server: it holds the data and does the storage work. KopiaUI becomes a client instead of touching the repository directly. It runs on the desktop or laptop, lives in the system tray, connects out to the server over HTTPS, authenticates with a username and password, and pushes backups in.

That buys you what Option A can’t: the client never sees the actual share credentials, per-user access control if the repository’s shared, maintenance that runs on an always-on host instead of an intermittent laptop, and a connection that isn’t SMB, reachable off the LAN if you ever want that. It’s also more setup, which is the rest of this post.

If Option A covers your case, stop here. Everything below is for Option B.

1. Create the htpasswd File First

Easy to miss: Unraid’s own Kopia template edit page has a note that says:

To run this container, you must create a htpasswd file (either via command line or using a tool such as a htpasswd generator) and place it in the /mnt/user/appdata/kopia/config directory, then adjust the Post Arguments accordingly.

Skip it and the Post Arguments in the next step point at a file that doesn’t exist, so the container has nothing to check credentials against and won’t come up cleanly.

Generate the file with the htpasswd command line tool (part of apache2-utils/httpd-tools) or any htpasswd generator site, username kopia, password whatever you want gating the server. Drop the resulting file at /mnt/user/appdata/kopia/config/htpasswd on the host, which is what /app/config/htpasswd resolves to inside the container. Keep that username matching the --server-username=kopia in the Post Arguments below. Kopia actually treats the htpasswd file and --server-username/--server-password as two separate credential stores, and its own docs describe the htpasswd file as holding user@hostname entries, so the relationship between them is murkier than Unraid’s note lets on. Matching them is what the template expects and what works. Diverge and you get a server that starts cleanly and then rejects every login with nothing useful to go on.

2. Stop the TLS Cert From Regenerating

This is the fingerprint mismatch from the intro. The fix is to pin the cert and key to a path inside your persistent appdata mount, so they survive the container being recreated instead of getting thrown away with it. This part is two steps, not one, don’t stop after the first.

Note that --insecure is gone from what follows. Replace the whole Post Arguments field rather than appending to what the template handed you, or you’ll be asking Kopia to run TLS and skip TLS at the same time.

In Unraid: Docker → Kopia container → Edit, then find the Post Arguments (or Repository Server Parameters) field and set it to:

server start --address 0.0.0.0:51515 --tls-cert-file /app/config/kopia.cert --tls-key-file /app/config/kopia.key --tls-generate-cert --htpasswd-file /app/config/htpasswd --server-username=kopia

Apply and let the container boot once. /app/config/ maps to your persistent appdata share, so --tls-generate-cert writes kopia.cert and kopia.key there, and Kopia reads back the htpasswd file you already dropped in from step 1.

Now go back and edit the Post Arguments again, this time dropping --tls-generate-cert for good:

server start --address 0.0.0.0:51515 --tls-cert-file /app/config/kopia.cert --tls-key-file /app/config/kopia.key --htpasswd-file /app/config/htpasswd --server-username=kopia

Leave --tls-generate-cert in place past that first boot and the container won’t start at all the next time you restart it, Kopia treats the flag as a one-time “generate,” not a “generate if missing.” With it removed, every boot from here on just points --tls-cert-file/--tls-key-file at the cert and key that already exist and reuses them. Fingerprint stays locked forever, or at least until you delete those two files yourself.

3. Create the Repository in the Web UI

The server has nothing to serve until a repository exists, and this is the one part of the setup that’s genuinely pleasant. Browse to https://<your-unraid-ip>:51515.

Your browser will object to the self-signed cert. Expected, click through it. Log in with the htpasswd credentials from step 1 and Kopia hands you a setup wizard: pick your storage (a filesystem path on the array is the obvious choice on Unraid, though B2, S3 and the rest are all in there), set a repository password, and it builds the repository for you.

That repository password is not the login you just used, and it’s the one that actually decrypts your backups. Lose it and the data is gone. No reset, no recovery, no support ticket. Put it in your password manager now rather than later. Step 6 is how you verify it without having to trust your memory.

4. Add a User for the Desktop App

The server needs an actual account before KopiaUI is allowed to authenticate against it. That’s not optional, even on your own LAN.

From the Unraid terminal:

docker exec -it Kopia kopia server users add kopia@desktop

The format is user@hostname, and both halves are yours to pick. I kept the user half as kopia to match the server login and used the client machine’s name for the other half. Usernames are case-sensitive. Get it wrong in KopiaUI and you just get a rejected connection, nothing pointing you back at the typo.

Set a password when prompted. The running server won’t pick the account up instantly. Kopia notices credential changes on its own within about five to ten minutes, or immediately if you restart the container, which is one click in the Unraid Docker tab and less waiting. There is a kopia server refresh command for this, but it wants the server address, the cert fingerprint, and credentials all passed to it, so restarting is genuinely the shorter path.

5. Connect KopiaUI

If you’ve got a broken profile hanging around from before the cert fix, clear it first: Repository → Disconnect in the KopiaUI menu bar.

Then Connect to Repository → Kopia Repository Server and fill in:

  • Server Address: https://<your-unraid-ip>:51515
  • SHA-256 Fingerprint: pulled from the Kopia container’s log for that first boot in step 2, the one where --tls-generate-cert actually ran
  • Username: kopia@desktop
  • Password: whatever you set in step 4

Can’t find it in the logs, or the one you copied from there just doesn’t match? KopiaUI itself will sometimes throw the actual fingerprint back at you in the connection error when it rejects an unrecognized cert, so try connecting once with a blank or wrong fingerprint first and see if it surfaces one you can copy from there instead.

Click connect. Assuming the cert is actually pinned now, this survives the next container restart instead of breaking again.

6. Checking Your Repository Password Without Leaking It

Better to confirm the password in your password manager matches what Kopia actually has now, not during a real restore. But typing it straight into docker exec puts it in your shell history and makes it visible in ps aux while the command runs. Not great for something that decrypts your backups.

read -rsp "Enter Password: " KOPIA_PASSWORD; echo
export KOPIA_PASSWORD
docker exec -i -e KOPIA_PASSWORD Kopia kopia repository status
unset KOPIA_PASSWORD

read -rs hides the input as you type, so nothing lands in your history. The ps aux half is subtler and easy to get wrong: -e KOPIA_PASSWORD with no value tells docker to pass the variable through from your environment, which is why the export is there. Write it the obvious way instead, -e KOPIA_PASSWORD="$KOPIA_PASSWORD", and your shell expands the password onto docker’s own command line, where anyone running ps aux can read it for as long as the command takes. Same idea, opposite result.

Four separate lines, not one && chain, for a reason: chain them and unset never runs when the password is wrong, which is exactly the case where you’re most likely to try again and leave it sitting in your environment.

A correct password gets you Storage provider:, Encryption:, and Format version: back. A wrong one throws an explicit invalid-password error. No ambiguity either way.

What’s in the UI vs. What Isn’t

SettingIn the Web UI?Where to actually manage it
Creating the repositoryYesWeb UI setup wizard
Schedules & retentionYesPolicies → Edit
Upload worker threadsYesPolicies → Upload
Compression algorithmYesPolicies → Compression
TLS certificate pinningNoDocker post arguments
Server basic auth (htpasswd)Nohtpasswd file in appdata config + Docker post arguments
User accountsNoCLI: kopia server users add

The web UI covers policy-level stuff reasonably well. Anything touching the server process itself (certs, auth, users) is CLI-only right now. Worth knowing going in so you’re not hunting through menus for something that isn’t there.