Host your own Kestrove
Your vault is encrypted on your devices before it is synced, so your server only ever stores data it can't read. Setup takes about five minutes.
What you need
- A Linux server or VPS with a public IP address. 1 CPU and 512 MB of RAM is plenty. Any distribution with Docker works.
- A domain or subdomain you control, for example
vault.example.com. - Ports 80 and 443 open to the internet, so your server can get its HTTPS certificate from Let's Encrypt.
1. Point your domain at the server
At your DNS provider, create an A record for your chosen name with your server's IPv4 address. Add an AAAA record too if the server has IPv6.
Using Cloudflare? Set the record to DNS only (grey cloud), not Proxied. Kestrove gets its own certificate and pins it in the apps, and Cloudflare's proxy would break both.
2. Install Docker
Skip this if docker compose version already works.
curl -fsSL https://get.docker.com | sudo sh
3. Get the files and run setup
mkdir kestrove && cd kestrove
curl -fsSLO https://kestrove.samialabri.com/host/compose.yaml
curl -fsSLO https://kestrove.samialabri.com/host/setup.sh
curl -fsSL https://kestrove.samialabri.com/host/env.example -o .env.example
chmod +x setup.sh
sudo ./setup.sh
The setup asks for your domain and an email address (for certificate notices only), creates a private .env file with a random setup code, checks your DNS, starts Kestrove and waits for HTTPS. At the end it prints your address and the setup code.
Prefer to do it by hand?
cp .env.example .env
nano .env # DOMAIN, ACME_EMAIL, and a KV_SETUP_CODE of at least 16 characters
chmod 600 .env
docker compose up -d
4. Create your account
- Open
https://your-domainin a browser. - Choose Create account and enter the setup code from step 3.
- Pick a strong master password. Kestrove then gives you a Secret Key.
- Save the Emergency Kit it offers, a PDF with your Secret Key and server address. Print it or store it somewhere safe. Without your master password and Secret Key, nobody can open the vault, including you. There is no reset.
The setup code stops working as soon as your account exists. That first account is the server's admin.
5. Add your devices
In the web vault go to Devices → Add a device. Then in the Kestrove app on your phone or computer choose Scan setup QR and scan it. Each new device needs your master password once.
Get the apps from the download section.
Inviting other people
One server can hold accounts for your family or team. Each person has their own vault, master password and Secret Key. As the admin you manage accounts, but you can't see, export or reset anyone's passwords.
- In the web vault open Admin → Invite someone. You can enter their email, so that only that address can use the invite, and choose how long it's valid (1, 7 or 30 days).
- Send them the invite link or show the QR code. It works once.
- They open the link, or choose Create a new account in any Kestrove app and enter the code with their email. Then they pick their own master password.
On the same page you can switch Sign-up to Open, so anyone who can reach the server may create an account, optionally only with certain email domains. You can also disable, delete or promote accounts. Someone who forgets their master password can't be recovered: delete their account and invite them again.
The web vault's code comes from your server, so whoever runs the server could in principle tamper with it. People who would rather not rely on that should use the Kestrove apps, which don't load code from the server.
Updating
cd kestrove
docker compose pull && docker compose up -d
KESTROVE_VERSION=latest in .env follows new releases. Set a version number instead, for example 1.1.0, to update only when you change it. Back up before a big update.
Backups
Your data lives in the Docker volume kestrove_data. Take a backup any time, even while Kestrove runs:
docker compose run --rm -T backup > kestrove-$(date +%F).db
Your vault inside the file is still end-to-end encrypted, so it's safe to keep on another machine or in cloud storage. For a nightly backup, run mkdir backups, then add this with crontab -e, changing the path to yours:
30 3 * * * cd /home/you/kestrove && docker compose run --rm -T backup > backups/kestrove-$(date +\%F).db && find backups -name 'kestrove-*.db' -mtime +30 -delete
To restore a backup onto a fresh install, after step 3, change the file name below to yours:
docker compose stop server
docker run --rm -v kestrove_data:/data -v "$PWD":/backup alpine \
sh -c 'cp /backup/kestrove-2026-01-31.db /data/kestrove.db && rm -f /data/kestrove.db-wal /data/kestrove.db-shm && chown 65532:65532 /data/kestrove.db'
docker compose start server
Anything changed on the server since the backup is gone from the server. Devices with newer data send it again on their next sync.
Troubleshooting
Setup warns the domain points elsewhere. Check the A record's IP, and "DNS only" on Cloudflare. DNS changes can take a few minutes.
The browser shows a certificate error. Run docker compose logs web. Ports 80 and 443 must be open in both your cloud firewall and ufw or firewalld.
Apps say they can't reach the server. Open https://your-domain on that device. If the server's IP changed, update the DNS record.
You lost the setup code. It's KV_SETUP_CODE in .env. If that was empty, run docker compose logs server | grep SETUP_TOKEN.
You want to start over. docker compose down -v deletes everything, then run ./setup.sh again.
To see what's happening, use docker compose logs -f for logs and docker compose ps for status.
What runs
server is the sync API. It stores encrypted vault data, device keys and a login verifier that is not your password. It runs as a non-root user on a read-only filesystem.
web is Caddy. It handles HTTPS certificates from Let's Encrypt, the security headers and the web vault, and it passes sync traffic to the server.
Nothing else is contacted: no telemetry, and no outside services besides Let's Encrypt.