docs / guides
Self-hosting a relay
Run botdb relay with the binary, Docker or systemd behind a TLS reverse proxy, and point clients at it.
A relay is a small HTTP server that stores encrypted change batches and snapshots and hands them to clients that prove they hold a database’s keys. It has no accounts and never sees plaintext. Anything that can run a binary or a container can host one.
Run it
botdb relay # 127.0.0.1:8787, data in ~/.botdb/relay
botdb relay --host 0.0.0.0 --token "$(openssl rand -hex 32)"
The relay listens on 127.0.0.1 by default. Use --host 0.0.0.0 when the reverse proxy runs on another host or in Docker. When it listens on a non-loopback address without a token, it prints a warning.
| Option | Env | Default | Description |
|---|---|---|---|
--host <ip> |
BOTDB_RELAY_HOST |
127.0.0.1 |
IP address to listen on. |
--port <port> |
PORT |
8787 |
Port. |
--data <dir> |
BOTDB_RELAY_DATA |
<home>/relay |
Data directory. Everything is stored in relay.db. |
--token <t> |
BOTDB_RELAY_TOKEN |
Require this token to register new databases. | |
--max-db-bytes <n> |
BOTDB_RELAY_MAX_DB_BYTES |
Storage limit per database, in bytes. | |
--retention-days <n> |
BOTDB_RELAY_RETENTION_DAYS |
7 |
Days to keep batches after a snapshot covers them. |
<home> is the botdb home directory (~/.botdb or BOTDB_HOME). Logs go to stderr; set the level with BOTDB_LOG (default info). The relay shuts down cleanly on Ctrl-C or SIGTERM.
Docker
The image runs botdb relay --host 0.0.0.0 --data /data as a non-root user, exposes port 8787 and has a health check on /health.
docker run -d --name botdb-relay \
-p 8787:8787 \
-v botdb-relay:/data \
-e BOTDB_RELAY_TOKEN=change-me \
ghcr.io/vimtor/botdb-relay
The image is published with releases. To build it yourself from a checkout of the repository:
docker build -f deploy/Dockerfile -t botdb-relay .
docker compose -f deploy/compose.yaml up -d # runs it with a named volume, building if needed
A compose file with Caddy terminating TLS:
# compose.yaml
services:
relay:
image: ghcr.io/vimtor/botdb-relay
environment:
BOTDB_RELAY_TOKEN: ${BOTDB_RELAY_TOKEN}
volumes:
- relay-data:/data
restart: unless-stopped
caddy:
image: caddy:2
command: caddy reverse-proxy --from relay.example.com --to relay:8787
ports:
- "80:80"
- "443:443"
volumes:
- caddy-data:/data
restart: unless-stopped
volumes:
relay-data:
caddy-data:
systemd
# /etc/systemd/system/botdb-relay.service
[Unit]
Description=botdb relay
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/botdb relay --data /var/lib/botdb-relay
Environment=BOTDB_HOME=/var/lib/botdb-relay
Environment=BOTDB_RELAY_TOKEN=change-me
DynamicUser=yes
StateDirectory=botdb-relay
Restart=on-failure
[Install]
WantedBy=multi-user.target
This listens on 127.0.0.1:8787 for a reverse proxy on the same host.
TLS
Run the relay behind a reverse proxy that terminates TLS. Payloads are already end-to-end encrypted, but TLS also protects request metadata, signatures and the registration token in transit.
The relay accepts request bodies up to 16 MiB, and clients push up to 4 MiB of batches per request, so raise the proxy’s body limit. Long-poll requests stay open for up to 30 seconds. With nginx:
server {
server_name relay.example.com;
# listen 443 ssl; certificates ...
client_max_body_size 16m;
location / {
proxy_pass http://127.0.0.1:8787;
proxy_buffering off;
}
}
Caddy’s defaults work without changes.
Registration token
A relay without a token lets anyone who can reach it register new databases and store data on it. Set BOTDB_RELAY_TOKEN (or --token) on the relay, and the same variable on clients. Clients send it as Authorization: Bearer <token> when they register a database, which happens the first time they push it to the relay.
The token only gates registration. Reads and writes to an existing database are authorized by signatures from that database’s keys, so people you invite don’t need the token to sync.
Point clients at it
export BOTDB_RELAY_TOKEN=change-me
botdb remote add https://relay.example.com --default # new databases and the vault
botdb remote add https://relay.example.com -d movies # an existing database
botdb remote ls
botdb doctor # checks that every remote is reachable
Or pick it during botdb login (u at the prompt). Changing the default remotes doesn’t move existing databases; add the relay to each one you want on it. A database can use a relay and a folder at the same time.
Operating notes
- Storage. The relay stores ciphertext only. Once a database has 1000 or more batches past its latest snapshot, a client uploads a new encrypted snapshot; the relay keeps one per database and deletes covered batches older than the retention period (default 7 days). Devices that are far behind, or new, start from the snapshot.
- Quotas. With
--max-db-bytes, pushes beyond the limit are rejected with507, and clients report aquotaerror. - Backups. Every client holds a full copy. If the relay loses its data, clients notice on the next sync and push everything again. Back up the data directory if you want faster recovery.
- Key rotation.
botdb rotate-keyswitches the database to new keys; the relay drops data from older key epochs. - Clocks. Requests are signed with a timestamp, and the relay rejects requests more than 5 minutes off its clock. Keep NTP running on the relay and clients.
- What it can see. Database ids, replica ids and sequence numbers, padded sizes, timing, client IP addresses and public keys. See Threat model.
The wire format is documented in Relay protocol.