Backup & Recovery
Open Source
Deploy Kopia Repository Server
Per-user authenticated multi-client backups proxied through a central server — only the VPS holds the storage credentials and repository password.
At a Glance
| Project | Kopia (server mode) |
| License | Apache 2.0 |
| Recommended Plan | RamNode Cloud VPS 2 GB+ |
| OS | Ubuntu 24.04 LTS |
| Backends | B2, S3, R2, Wasabi, GCS, Azure, SFTP |
Looking for the single-host backup client?
See our Kopia (single-machine) guide. This page covers repository server mode for multi-client deployments.
1
Install Kopia + Service User
Add APT repo
sudo apt update && sudo apt -y full-upgrade
sudo apt -y install ca-certificates curl gnupg apache2-utils ufw
sudo install -m 0755 -d /etc/apt/keyrings
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 -y install kopia
kopia --version
sudo useradd -r -m -d /var/lib/kopia -s /bin/bash kopia2
Prepare the Repository Backend (Backblaze B2)
Create or connect
sudo -iu kopia
# Create ONCE for a brand new repository:
kopia repository create b2 \
--bucket=my-backup-bucket \
--key-id="$B2_KEY_ID" \
--key="$B2_APPLICATION_KEY"
# (Set a long passphrase — losing it means losing the data.)
# Or connect to an existing repository:
kopia repository connect b2 \
--bucket=my-backup-bucket \
--key-id="$B2_KEY_ID" \
--key="$B2_APPLICATION_KEY"
kopia repository status3
Generate Internal TLS Material
Self-signed cert (Caddy will validate publicly)
sudo -iu kopia
mkdir -p ~/.config/kopia/tls
cd ~/.config/kopia/tls
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout server.key -out server.cert -days 3650 \
-subj "/CN=kopia-internal"
chmod 600 server.key4
Per-Client User Database (htpasswd)
Use bcrypt (-B)
htpasswd -cB ~/.config/kopia/htpasswd alice@laptop
htpasswd -B ~/.config/kopia/htpasswd bob@desktop
htpasswd -B ~/.config/kopia/htpasswd web01@production5
systemd Service
control password
openssl rand -base64 32 > ~/.config/kopia/control.password
chmod 600 ~/.config/kopia/control.password/etc/systemd/system/kopia-server.service
[Unit]
Description=Kopia Repository Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=kopia
Group=kopia
WorkingDirectory=/var/lib/kopia
Environment=HOME=/var/lib/kopia
ExecStart=/usr/bin/kopia server start \
--address=127.0.0.1:51515 \
--tls-cert-file=/var/lib/kopia/.config/kopia/tls/server.cert \
--tls-key-file=/var/lib/kopia/.config/kopia/tls/server.key \
--htpasswd-file=/var/lib/kopia/.config/kopia/htpasswd \
--server-control-username=control \
--server-control-password-file=/var/lib/kopia/.config/kopia/control.password \
--no-ui
Restart=on-failure
RestartSec=10
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/kopia
ProtectKernelTunables=true
[Install]
WantedBy=multi-user.targetEnable
sudo systemctl daemon-reload
sudo systemctl enable --now kopia-server
journalctl -u kopia-server -f6
Caddy Reverse Proxy + Let's Encrypt
Install Caddy
sudo apt -y install debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt -y install caddy/etc/caddy/Caddyfile
backup.example.com {
encode zstd gzip
request_body { max_size 10GB }
reverse_proxy 127.0.0.1:51515 {
transport http {
tls
tls_insecure_skip_verify
response_header_timeout 600s
read_timeout 600s
write_timeout 600s
}
}
}Reload + firewall
sudo systemctl reload caddy
sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
sudo ufw deny 51515/tcp && sudo ufw enable
curl -v https://backup.example.com/api/v1/repo/status7
Connect a Client
From any machine with kopia installed
kopia repository connect server \
--url=https://backup.example.com \
--override-username=alice \
--override-hostname=laptop
kopia snapshot create ~/Documents
kopia policy set --global --keep-latest=10 --keep-hourly=24 --keep-daily=7The client never sees the backend credentials or the repository password — only its own htpasswd credential and the server URL.
8
Centralized Maintenance
Make the server the maintenance owner
sudo systemctl stop kopia-server
sudo -iu kopia
kopia maintenance set --owner=$(hostname)
kopia maintenance set --enable-quick=true --enable-full=true
kopia maintenance set --quick-interval=1h --full-interval=24h
exit
sudo systemctl start kopia-serverHardening Beyond Defaults
- Object lock on B2 / S3 with retention exceeding your Kopia policy — strongest ransomware protection
- Per-user ACLs via
kopia server aclto scope users to their own sources - fail2ban on Caddy 401 responses
- Off-host backup of
/var/lib/kopia/.config/kopia/(gpg-encrypted tar to a second bucket)
