Skip to content

Yundera/hubs-seed

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hubs-seed

Provisioning toolkit for self-hosted Hubs (Reticulum) deployments. Two subcommands:

  • bootstrap — generates Phoenix/Guardian/PostgREST secrets, an RSA permissions keypair, and the docker-compose .env file. Replaces a host-side install.sh. Runs before the stack starts.
  • seed — waits for reticulum/health, mints an admin token, uploads the default scene, sets the app logo + name. Runs after the stack is healthy.

Latest tag: ghcr.io/worph/hubs-seed:2.0.0.

What you get out of the box

The image bundles a CC0 default — Quaternius's Outdoor Market (~1.2 MB GLB, open-air plaza). Override any of it via env vars; everything is optional.

bootstrap

Generates secrets and writes them to a docker-compose .env. Idempotent: existing secrets are preserved across re-runs, but framework-passthrough vars (APP_DOMAIN, APP_PUBLIC_IP_DASH, ...) are always refreshed from the current environment.

docker run --rm \
  -v /DATA/AppData/hubs:/data/hubs \
  -v /DATA/AppData/casaos/apps/hubs:/data/compose \
  -e APP_DOMAIN -e APP_PUBLIC_IP_DASH -e APP_PUBLIC_IPV4 \
  -e APP_EMAIL -e PUID -e PGID \
  ghcr.io/worph/hubs-seed:2.0.0 bootstrap

Writes:

Path Contents
/data/compose/.env docker-compose env file (framework vars + secrets)
/data/hubs/perms.key.pem RSA private key (Reticulum permissions service)
/data/hubs/perms.pub.pem RSA public key
/data/hubs/config.toml.template Reticulum config template (bundled in image)

Re-running on an existing install:

  • preserves every secret already in .env (DB password, Phoenix/Guardian/PostgREST keys);
  • preserves the existing keypair (regenerating would invalidate Guardian tokens);
  • always refreshes APP_DOMAIN/APP_PUBLIC_IP_DASH/APP_PUBLIC_IPV4/APP_EMAIL/PUID/PGID — these are passthroughs from the framework's shell env, and on redeploy the framework is the source of truth;
  • always rewrites config.toml.template (so template fixes ship via image upgrades).

bootstrap environment

Var Default Notes
APP_DOMAIN "" Customer-facing host root (e.g. wisera.inojob.com). Written into .env so docker-compose's --env-file pass doesn't shadow it with empty at deploy time.
APP_PUBLIC_IP_DASH "" Server public IPv4 with .- (e.g. 185-194-219-244). Required for the Caddy hubs-<ip>.nip.io vhost the Cloudflare Worker rewrites Host to.
APP_PUBLIC_IPV4 "" Same IP, dotted.
APP_EMAIL "" Reticulum admin_email. Required by the seed step too.
PUID / PGID 1000 / 1000 Host UID/GID for the secrets and templates so the runtime container (which runs as PUID) can read them.
HUBS_APP_DIR /data/hubs Override for CI/test only.
HUBS_COMPOSE_DIR /data/compose Override for CI/test only.

seed

docker run --rm \
  --network <hubs-stack-network> \
  -v /path/to/secrets.env:/secrets.env:ro \
  -e SECRETS_ENV_FILE=/secrets.env \
  -e RET_INTERNAL_URL=https://hubs-reticulum:4000 \
  -e RET_PUBLIC_URL=https://hubs.example.com \
  -e APP_EMAIL=admin@example.com \
  ghcr.io/worph/hubs-seed:2.0.0 seed

That's the whole content seed on a "turkey-style" Reticulum deployment (the standard Hubs-Foundation/reticulum image with TURKEY_MODE=1).

Calling the image without a subcommand defaults to seed, for back-compat with post-install-cmd blocks pinned to 1.x.

How it works

  1. Polls RET_INTERNAL_URL/health until 200.
  2. Mints a Guardian admin JWT using one of three auth sources (see below).
  3. Idempotency probe — GET /api/v1/media/search?source=scene_listings&filter=default. If any entry exists, exits 0.
  4. Uploads scene .glb + screenshot to POST /api/v1/media.
  5. POST /api/v1/scenes (creates the Scene with the uploaded files).
  6. INSERTs the SceneListing row via /api/postgrest/scene_listings with tags={"tags":["default"]} — that's the same query Hub.create uses to pick a default.
  7. Uploads the bundled logo.png and writes images.logo + translations.en.app-name to /api/v1/app_configs.

Auth: three ways to provide a token

Pick whichever fits your wiring. Tried in this order:

  1. ADMIN_TOKEN — pre-minted Guardian JWT. Use this if you have your own minting flow.
  2. DASHBOARD_ACCESS_KEY + APP_EMAIL — calls POST /api-internal/v1/make_auth_token_for_email (gated by dashboard_access_key in config.toml, only enabled when Reticulum runs with TURKEY_MODE=1).
  3. DASHBOARD_ACCESS_KEY_FILE — same as above but read the key from a file path.
  4. SECRETS_ENV_FILE — same as above but parse the key out of a Reticulum-style secrets.env (looks for DASHBOARD_ACCESS_KEY= or turkeyCfg_DASHBOARD_ACCESS_KEY=).

Mode 4 is the easiest in a Yundera/CasaOS post-install-cmd: bind-mount the existing secrets.env and you're done.

Environment

Var Required Default Notes
RET_INTERNAL_URL no https://hubs-reticulum:4000 Container-network reticulum URL. TLS verification is disabled (self-signed).
RET_PUBLIC_URL no (none) Public base URL. Used to rewrite the images.logo URL we store in app_configs so the browser can fetch it; fall back to the upload's reported origin.
APP_EMAIL conditional Required for token-mint modes (everything except ADMIN_TOKEN). Must match Reticulum's admin_email.
ADMIN_TOKEN one of Pre-minted Guardian JWT.
DASHBOARD_ACCESS_KEY one of Direct value of Reticulum's dashboard key.
DASHBOARD_ACCESS_KEY_FILE one of Path to a file containing the key.
SECRETS_ENV_FILE one of Path to a secrets.env-style file.
SCENE_GLB_URL no bundled assets/scene.glb Override the default scene model.
SCENE_SCREENSHOT_URL conditional bundled assets/scene.png (if present) Reticulum's DB schema requires a screenshot. Either set this env var or bundle assets/scene.png; otherwise the seeder errors out before creating the scene.
SCENE_SPOKE_URL no bundled assets/scene.spoke (if present) Override the Spoke project file. Optional — recommended so admins can re-edit the scene.
SCENE_NAME no World Lounge
SCENE_DESCRIPTION no "A relaxed lounge to gather in..."
SCENE_ATTRIBUTIONS no "" Free-text shown in scene metadata.
APP_LOGO_URL no bundled assets/logo.png Override the app logo.
APP_HOME_BACKGROUND_URL no bundled assets/home_background.png Override the home-page hero image.
APP_NAME no Hubs Sets translations.en.app-name.

Idempotency

The probe (scene_listings?filter=default) is the safety check. Once an admin has customized the default scene, hubs-seed will never overwrite it.

Bundled assets

Under assets/:

  • scene.glb — Default 3D scene (currently World Lounge, a Spoke export).
  • scene.spoke — Spoke project file. Admins can re-open this in Spoke to edit the scene.
  • scene.png — Optional preview thumbnail for the scene listing. If absent, the listing has no thumbnail.
  • logo.png — Default app logo.
  • home_background.png — Hero image on the landing page (separate from the scene preview).

See assets/ATTRIBUTION.md for licensing details.

License

MIT

About

Provisioning toolkit for self-hosted Mozilla Hubs (Reticulum). Bootstraps secrets and seeds the default scene, logo, and admin config in one container. Built for Yundera and CasaOS post-install workflows.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 99.1%
  • Dockerfile 0.9%