Host everything on the website: hosting guide, setup files, downloads; source code button

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-30 18:55:35 +04:00
co-authored by Claude Opus 5.5
parent cac68780ee
commit 92929e3194
14 changed files with 342 additions and 14 deletions
+124
View File
@@ -0,0 +1,124 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Host Kestrove</title>
<meta name="description" content="Run your own Kestrove server on any Linux machine with Docker. Setup takes about five minutes.">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/legal.css">
</head>
<body>
<main>
<p class="home"><a href="/">Kestrove home</a></p>
<header><img src="/favicon.svg" alt=""><h1>Host your own Kestrove</h1></header>
<p>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.</p>
<section>
<h2>What you need</h2>
<ul>
<li>A Linux server or VPS with a public IP address. 1 CPU and 512 MB of RAM is plenty. Any distribution with Docker works.</li>
<li>A domain or subdomain you control, for example <code>vault.example.com</code>.</li>
<li>Ports <strong>80</strong> and <strong>443</strong> open to the internet, so your server can get its HTTPS certificate from Let's Encrypt.</li>
</ul>
</section>
<section>
<h2>1. Point your domain at the server</h2>
<p>At your DNS provider, create an <strong>A record</strong> for your chosen name with your server's IPv4 address. Add an <strong>AAAA record</strong> too if the server has IPv6.</p>
<p>Using Cloudflare? Set the record to <strong>DNS only</strong> (grey cloud), not Proxied. Kestrove gets its own certificate and pins it in the apps, and Cloudflare's proxy would break both.</p>
</section>
<section>
<h2>2. Install Docker</h2>
<p>Skip this if <code>docker compose version</code> already works.</p>
<pre><code>curl -fsSL https://get.docker.com | sudo sh</code></pre>
</section>
<section>
<h2>3. Get the files and run setup</h2>
<pre><code>mkdir kestrove &amp;&amp; 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</code></pre>
<p>The setup asks for your domain and an email address (for certificate notices only), creates a private <code>.env</code> file with a random <strong>setup code</strong>, checks your DNS, starts Kestrove and waits for HTTPS. At the end it prints your address and the setup code.</p>
<details>
<summary>Prefer to do it by hand?</summary>
<pre><code>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</code></pre>
</details>
</section>
<section>
<h2>4. Create your account</h2>
<ol>
<li>Open <code>https://your-domain</code> in a browser.</li>
<li>Choose <strong>Create account</strong> and enter the setup code from step 3.</li>
<li>Pick a strong master password. Kestrove then gives you a <strong>Secret Key</strong>.</li>
<li><strong>Save the Emergency Kit</strong> 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.</li>
</ol>
<p>The setup code stops working as soon as your account exists. That first account is the server's <strong>admin</strong>.</p>
</section>
<section>
<h2>5. Add your devices</h2>
<p>In the web vault go to <strong>Devices → Add a device</strong>. Then in the Kestrove app on your phone or computer choose <strong>Scan setup QR</strong> and scan it. Each new device needs your master password once.</p>
<p>Get the apps from the <a href="/#download">download section</a>.</p>
</section>
<section>
<h2>Inviting other people</h2>
<p>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 <strong>can't see, export or reset anyone's passwords</strong>.</p>
<ol>
<li>In the web vault open <strong>Admin → Invite someone</strong>. 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).</li>
<li>Send them the invite link or show the QR code. It works once.</li>
<li>They open the link, or choose <strong>Create a new account</strong> in any Kestrove app and enter the code with their email. Then they pick their own master password.</li>
</ol>
<p>On the same page you can switch <strong>Sign-up</strong> to <em>Open</em>, 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.</p>
<p>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.</p>
</section>
<section>
<h2>Updating</h2>
<pre><code>cd kestrove
docker compose pull &amp;&amp; docker compose up -d</code></pre>
<p><code>KESTROVE_VERSION=latest</code> in <code>.env</code> follows new releases. Set a version number instead, for example <code>1.1.0</code>, to update only when you change it. Back up before a big update.</p>
</section>
<section>
<h2>Backups</h2>
<p>Your data lives in the Docker volume <code>kestrove_data</code>. Take a backup any time, even while Kestrove runs:</p>
<pre><code>docker compose run --rm -T backup &gt; kestrove-$(date +%F).db</code></pre>
<p>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 <code>mkdir backups</code>, then add this with <code>crontab -e</code>, changing the path to yours:</p>
<pre><code>30 3 * * * cd /home/you/kestrove &amp;&amp; docker compose run --rm -T backup &gt; backups/kestrove-$(date +\%F).db &amp;&amp; find backups -name 'kestrove-*.db' -mtime +30 -delete</code></pre>
<p><strong>To restore</strong> a backup onto a fresh install, after step 3, change the file name below to yours:</p>
<pre><code>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 &amp;&amp; rm -f /data/kestrove.db-wal /data/kestrove.db-shm &amp;&amp; chown 65532:65532 /data/kestrove.db'
docker compose start server</code></pre>
<p>Anything changed on the server since the backup is gone from the server. Devices with newer data send it again on their next sync.</p>
</section>
<section>
<h2>Troubleshooting</h2>
<p><strong>Setup warns the domain points elsewhere.</strong> Check the A record's IP, and "DNS only" on Cloudflare. DNS changes can take a few minutes.</p>
<p><strong>The browser shows a certificate error.</strong> Run <code>docker compose logs web</code>. Ports 80 and 443 must be open in both your cloud firewall and <code>ufw</code> or <code>firewalld</code>.</p>
<p><strong>Apps say they can't reach the server.</strong> Open <code>https://your-domain</code> on that device. If the server's IP changed, update the DNS record.</p>
<p><strong>You lost the setup code.</strong> It's <code>KV_SETUP_CODE</code> in <code>.env</code>. If that was empty, run <code>docker compose logs server | grep SETUP_TOKEN</code>.</p>
<p><strong>You want to start over.</strong> <code>docker compose down -v</code> deletes everything, then run <code>./setup.sh</code> again.</p>
<p>To see what's happening, use <code>docker compose logs -f</code> for logs and <code>docker compose ps</code> for status.</p>
</section>
<section>
<h2>What runs</h2>
<p><strong>server</strong> 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.</p>
<p><strong>web</strong> 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.</p>
<p>Nothing else is contacted: no telemetry, and no outside services besides Let's Encrypt.</p>
</section>
</main>
</body>
</html>