osrs-data-hub

Kubernetes

Run the published images on a cluster instead of Docker Compose.

The hub publishes two images to GHCR for every release. Run them on a cluster with the same environment variables as a Compose deployment; there is no Kubernetes-specific setting.

ImageListens onNotes
ghcr.io/redfirebreak/osrs-data-hub-web:<x.y.z>3000Web app, plugin endpoints and API.
ghcr.io/redfirebreak/osrs-data-hub-worker:<x.y.z>WORKER_METRICS_PORT (9464)Scheduled jobs. Also the migration image.

There is no latest tag: pin an exact version and bump it with Renovate or by hand. Releases are tagged <major>.<minor>.<patch> and <major>.<minor>. A major bump means a deployment has to change something to upgrade, and the release notes say what.

What a deployment relies on

  • Users. Both images run as node (uid 1000) with node as PID 1, and need no capabilities.
  • One replica each. Run exactly one web and one worker pod: rate limits and the live stream are kept in the web process's memory.
  • Migrations run as an initContainer from the worker image: node --enable-source-maps dist/migrate.js with DATABASE_URL. It exits 0 once every migration is applied.
  • Probes. GET /api/health on the web pod is both the readiness and the liveness probe. The worker has no health endpoint; its liveness is the process.
  • Database. The same timescale/timescaledb:<version>-pg18 image as compose.yaml, with TS_TUNE_MEMORY, TS_TUNE_MAX_CONNS=100 and TIMESCALEDB_TELEMETRY=off, and its volume mounted at /var/lib/postgresql.
  • Proxy chain. Set TRUST_PROXY_HOPS to the number of proxies that append to X-Forwarded-For. Behind Cloudflare → cloudflared → Traefik that is 2. Traefik streams text/event-stream by default, and the live stream's 25 s heartbeat keeps tunnels from closing it.
  • Metrics. Deny /metrics on the public ingress, and scrape the web and worker Services in-cluster with METRICS_TOKEN, as jobs hub-web and hub-worker.

On this page