Skip to content
open tomato/ rafa-hub
GitHub
rafa-hub pages
  1. rafa-hub
  2. Run a hub

Run a hub

Build the rafa-hub container from rafa's repository, give it a config, and check it answers before any device connects.

This page runs a hub for trying it out, with the recipe in rafa's repository. It has no orchestration, image publishing or log shipping; a production deployment is an open spec (#503).

What you need

  • A checkout of rafa's repository, because the image is built from its root.
  • Docker.
  • A GitHub repository whose collaborators are the people allowed to sync. The hub reads its permissions; it does not need to be the project's own repository.

1. Write the config

The hub reads a YAML file. Only hub.repository is required:

hub:
  repository: your-org/your-repo
  port: 7373
  auth:
    cacheFor: 10m
KeyDefaultWhat it sets
hub.repositorynone, requiredthe repository, as owner/name, whose permissions decide who may sync
hub.port7373the port, 1 to 65535
hub.storePathrafa-hub.sqlite beside the configthe SQLite store; a relative path is read from the config file's folder
hub.auth.cacheFor10mhow long the hub keeps GitHub's answer about a token, from 1m to 24h, or false to ask on every request

2. Build and run the container

From the root of the rafa checkout:

docker build -f packages/rafa-hub/Dockerfile -t rafa-hub .
docker run -d -p 7373:7373 -v rafa-hub-data:/data rafa-hub

The container reads its config from /data/rafa-hub.yaml, so put the file in the rafa-hub-data volume. With hub.storePath left out, the store is created beside the config in /data, and it outlives a restart of the container. [verify: the Docker build and run; the Docker daemon was not running here, so the hub was run from source instead, as below]

Outside a container, the hub reads the config file named by the RAFA_HUB_CONFIG environment variable. From the rafa checkout, with Bun:

RAFA_HUB_CONFIG=/path/to/rafa-hub.yaml bun packages/rafa-hub/src/bin.ts

3. Check it answers

The hub writes its logs as JSON lines on standard output (docker logs in a container). Once it starts:

{"time":"…","level":"info","event":"listening","port":7399,"version":"0.0.0"}
{"time":"…","level":"info","event":"store.opened"}

Then ask its health route (the run shown used port 7399 in its config; use your own port):

curl http://127.0.0.1:7399/health
{"success":true,"data":{"status":"ok","version":"0.0.0"}}

The hub answers 503 until its store opens. The container's own health check asks the same route every 30 seconds, so a failing check means the store did not open or the hub did not start; the logs say which.

Who may sync

Each device sends a GitHub token with every request. The hub asks GitHub what that login may do on hub.repository, and serves it when the login holds admin, maintain or write access. A request with no token is refused, naming the rule and the configured repository (here, the run's open-tomato/rafa):

{"success":false,"error":"Send a GitHub token for a login with admin, maintain, write on open-tomato/rafa as Authorization: Bearer."}

No deploy keys or personal access tokens are stored on the hub.