Self-host
Requirements
Section titled “Requirements”- Docker + Docker Compose v2
- 4 GB RAM minimum (indexd alone takes ~1 GB)
- A funded Sia wallet — you need storage contracts before pins land
- A domain + TLS terminator if you want public access
Clone + configure
Section titled “Clone + configure”git clone <your-fork> siahubcd siahubcp ops/.env.example .env$EDITOR .envRequired env vars:
| Var | Note |
|---|---|
SIAHUB_POSTGRES_PASSWORD | Any long random string |
REDIS_PASSWORD | Any long random string |
GATEWAY_URL_SIGNING_KEY | base64(32 random bytes) |
XET_JWT_SIGNING_KEY | base64(32 random bytes) |
SIAHUB_APP_ID / SIAHUB_APP_KEY | From make bootstrap (below) |
INDEXD_ADMIN_PASSWORD | Any long random string |
GITHUB_OAUTH_CLIENT_ID + _SECRET | From your GitHub OAuth app |
CAS_PUBLIC_URL | The URL clients reach — http://localhost:8080 for local |
Bootstrap a Sia app key
Section titled “Bootstrap a Sia app key”First boot only:
make bootstrap # writes SIAHUB_APP_ID + SIAHUB_APP_KEY to .envThis prompts indexd for a fresh app key and prints the recovery phrase.
Do not lose the phrase — it’s the only way to re-derive the same
key if you ever need to migrate. SiaHub operators keep the phrase in
the .env; losing it orphans all stored bytes.
docker compose -f ops/docker-compose.yml --env-file .env up -dServices come up in ~30 s; indexd takes longer on first sync (several
minutes while it pulls the chain tip). The console at localhost:5173
stays in “Loading…” until /admin/me returns.
TLS + custom domain
Section titled “TLS + custom domain”A Caddy config template lives in ops/Caddyfile. Point your domain at
the box and run Caddy with that config; it will handle ACME
automatically. For nginx-based setups, copy the upstreams from the
compose file and front them however you prefer.