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>:

CommandPurpose
sitebin listList all sites (id, size, files, mode, created, owner/domains).
sitebin reportsList 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 caddyfilePrint the generated Caddyfile.
sitebin healthcheckProbe 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, so docker ps shows the instance's health out of the box.
  • Freeze: SITEBIN_READONLY=true disables 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.

Never run two containers on the same, shared, or bidirectionally synced volume — multi-step operations (uploads with quota enforcement, index updates, replace-all) can interleave and corrupt state. Active–active is not supported.

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.
Open, no-login file hosting attracts phishing and malware. As the operator you are responsible for what your instance serves: keep the takedown command handy, consider tight 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.