Operations & security
Day-two life with a Sitebin instance: the operator CLI, backups, health, and what you should know before hosting strangers' content on the public internet.
Operator commands
All operator commands run inside the container, e.g.
docker exec sitebin sitebin <cmd>:
| Command | Purpose |
|---|---|
sitebin list | List all sites (id, size, files, mode, created, owner/domains). |
sitebin reports | List filed abuse reports. |
sitebin delete <id|domain> | Take down a site by view id, edit id, or domain. |
sitebin backup [file] | Write a gzip tar of /data (stdout if no file). |
sitebin restore <file> | Restore /data from a backup. |
sitebin caddyfile | Print the generated Caddyfile. |
sitebin healthcheck | Probe the internal health endpoint. |
Backup
The /data volume is everything — sites, indexes, and
certificates. Back up that path and you have backed up the whole
instance. Alternatively, sitebin backup streams a snapshot:
docker exec sitebin sitebin backup - > sitebin-$(date +%F).tar.gz
Restore a snapshot with sitebin restore <file>.
Health, freeze, and logs
- Health: the image ships a
HEALTHCHECK, sodocker psshows the instance's health out of the box. - Freeze:
SITEBIN_READONLY=truedisables new-site creation — existing sites keep serving. - Logs: structured request + lifecycle logs on stdout
(
docker logs).
Availability & failover
Sitebin is a single-writer system: writes are
serialized by in-process locks, so exactly one instance
may run against a given /data at any time.
Everything else about the design makes failover easy: the container is
disposable and /data is the entire instance — sites,
indexes, accounts, certificates, and the .secret that keeps
sessions valid across a move.
Baseline: restore to a fresh server
With streaming backups and a low DNS TTL, this alone gives minutes-level recovery — and it's the plan every deployment should have and test:
# continuously (cron) on the primary: docker exec sitebin sitebin backup - | ssh backup-host 'cat > sitebin-latest.tar.gz' # disaster: on any fresh server with Docker docker run -d --name sitebin -v sitebin-data:/data … sitebin:latest # same env as before cat sitebin-latest.tar.gz | docker exec -i sitebin sitebin restore /dev/stdin docker restart sitebin # point DNS (base domain, wildcard, custom domains) at the new server; # certificates re-issue automatically if missing.
Keep the compose/env file in version control — server + compose file + backup is the complete instance.
Active–passive standby
When minutes of downtime are too many: replicate the volume
block-level to a second server — DRBD (synchronous, RPO ≈ 0) or ZFS
send/recv on a tight interval — with the container
stopped on the standby. On failure, promote the replica, start
the container, and move the floating IP (or flip low-TTL DNS). The one
inviolable rule is the single-writer rule: make sure the old primary is
down (fencing) before the standby starts.
Read replicas (one writer, many readers for view traffic) are architecturally feasible and on the enterprise roadmap, but not implemented today.
Security notes
- User content is only served on random subdomains and custom domains — never on the main domain. Each site gets its own origin.
- Passwords are stored as Argon2id hashes; password attempts (API, gate, and WebDAV) are rate limited per IP and per site.
- Uploads are sanitized against path traversal; symlinks in zips are rejected; per-site size/count quotas are enforced during streaming.
- The authz/tls-check/health endpoints live on a separate listener that is never proxied publicly.
SITEBIN_MAX_* limits and SITEBIN_MAX_EXPIRY_DAYS,
and put the instance behind abuse monitoring if it is exposed to
strangers.Anyone can flag a site through the public abuse-report endpoint
(POST /api/report, no auth required); filed reports show up
in sitebin reports.