Skip to content

Tech Stack

ScottyLabs platform overview. Pan and zoom the diagram below (scroll or pinch inside the frame; use the toolbar zoom controls). Hover the diagram and click fullscreen for a larger view. Repo boxes link to Codeberg when clicked. Orange borders or * mark services that export Prometheus metrics.

The diagram reads left to right: governance, then infra-01 and deploy-01. On every host, Tailscale (Headscale client) and host exporters run alongside Caddy. Public web traffic hits Caddy first; tailnet-only services like pgAdmin use Headscale → Caddy → app (the reverse order from the Caddy OIDC proxy pattern). Cross-host links are described in prose below the diagram.

Sources: governance team data, infrastructure NixOS hosts, and this monorepo checkout.

Platform

Hand-laid-out in Excalidraw. Edit documentation/scripts/generate-tech-stack-excalidraw.ts and run bun run generate:tech-stack-diagram, or export from excalidraw.com and replace public/diagrams/tech-stack.excalidraw.json.

Diagram key: orange border or * = Prometheus service metrics. Host exporters (node, systemd, cAdvisor, comin) run on every NixOS host; the Prometheus scraper on infra-01 collects them along with service metrics.

Tailscale on every host: each VM runs a Tailscale client registered with the Headscale server on infra-01. Headplane (admin UI) runs only on infra-01. pgAdmin is tailnet-only (:5050 on tailscale0); reach it via Headscale → Caddy → pgAdmin, not from the public internet.

Forgejo CI on infra-01 sends deploy webhooks to kennel on deploy-01. Kennel registers app routes on deploy-01 Caddy via the admin API. Keycloak is the org IdP; see Authentication.

Authentication

Keycloak (idp.scottylabs.org) is the org IdP. Caddy always terminates TLS and reverse-proxies, but where the OIDC login happens differs:

Caddy OIDC proxy

For apps that need auth but do not implement OIDC themselves, Caddy’s caddy-security plugin handles the full login dance: redirect to Keycloak, establish a session, then proxy to the backend.

Browser → Caddy (OIDC gate) ⇄ Keycloak → Caddy → app

Example: Garage WebAdmin (garage.scottylabs.org) — static UI with no OIDC support; Caddy authenticate / authorize routes gate /auth/* and /api/* before reaching Garage’s admin API and the WebAdmin bundle.

Native OIDC

For apps that speak OIDC themselves, Caddy is a plain reverse proxy on the public web path. The browser talks to the app; the app redirects to Keycloak and completes the OAuth flow on its own.

Browser → Caddy → app ⇄ Keycloak

Examples on infra-01:

ServiceCaddy routeApp-side auth
OpenBaosecrets2.scottylabs.org:8200JWT auth backend + Keycloak (via OpenTofu tofu/identity)
Headscale serverheadscale.scottylabs.org → Headscale APIOIDC in Headscale (client_id: headscale)
Headplaneheadplane.scottylabs.org → Headplane UIOIDC in Headplane (client_id: headplane); admin UI for Headscale
Grafanagrafana.scottylabs.org → Grafanageneric_oauth to Keycloak
LiteLLMlitellm.scottylabs.org → LiteLLMGeneric OIDC SSO (GENERIC_* env)

Tailnet-first (Headscale before Caddy)

Some services are not on the public internet. Every NixOS host runs a Tailscale client joined to the org Headscale server (infra-01 only). For tailnet-only admin tools, you connect over Headscale first, then Caddy, then the app — the opposite order from the Caddy OIDC proxy pattern:

Admin → Headscale (Tailscale) → Caddy → pgAdmin

pgAdmin listens on :5050 on the tailscale0 interface on hosts with PostgreSQL (infra-01, deploy-01). Public Caddy routes do not expose it.

Application repos

Kennel builds and deploys repos marked kennel = true in governance. Those deployments live inside the kennel area on deploy-01 in the platform diagram above.

Prometheus exporters

Grafana on infra-01 queries the Prometheus scraper there. Metrics come from two layers:

  1. Host exporters on every NixOS host (infra-01, deploy-01, snoopy, bus-sign-display) — node, systemd, cAdvisor, and comin metrics. These appear as Host exporters nodes in the platform diagram.
  2. Service metrics on individual platform services — marked with * or an orange border in the diagram. Scraped by Prometheus on infra-01 (see observability.nix). Dashboards and alerts live in observability.

Host exporters (every NixOS host)

Scrape jobExporterPortHosts
nodenode_exporter9100infra-01, deploy-01, snoopy, bus-sign-display
systemdsystemd_exporter9558infra-01, deploy-01, snoopy, bus-sign-display
cadvisorcAdvisor4194infra-01, deploy-01, snoopy
comincomin built-in metrics4243infra-01, deploy-01, snoopy, bus-sign-display

systemd_exporter whitelists: kennel, caddy, postgresql, valkey, garage, loki, tempo, grafana, prometheus, opentelemetry-collector, promtail.

Service metrics (infra-01 unless noted)

Scrape jobServiceMetrics sourceGrafana dashboard
prometheusPrometheus scraperself-scrape :9090
grafanaGrafananative :3000
lokiLokinative :3101/metrics
tempoTemponative :3200
otel-collectorOpenTelemetry Collectornative :8888
keycloakKeycloaknative :9092infra/keycloak
keycloak-eventsKeycloakrealm metrics :8080/realms/master/metricsinfra/keycloak
openbaoOpenBao:8200/v1/sys/metricsinfra/openbao
garageGaragenative :3903infra/garage
headscaleHeadscale servernative :9091infra/headscale
postgresPostgreSQLpostgres_exporter :9187infra/postgres
caddyCaddyadmin API :2019infra/caddy
synapseSynapse (Matrix)/_synapse/metrics :9008infra/synapse
litellmLiteLLMprometheus-client /metrics :4000infra/litellm
atlantisAtlantis/metrics :4141infra/atlantis
uptime-kumaUptime Kuma/metrics :3001 (API key auth)
kennelKennelnative :3001kennel/overview (deploy-01)

Garage WebAdmin uses the Caddy OIDC proxy pattern; Garage S3 API (s3.scottylabs.org) has no OIDC gate. LiteLLM fronts cli-proxy-api on localhost (no scrape job yet). infra/service-health aggregates systemd and node metrics across hosts.

Layers

LayerRolePrimary repos
GovernanceTeams, repos, identities, and OpenTofu for Forgejo/GitHub/Keycloak/Discord/Slackgovernance
InfrastructureDeclarative NixOS on campus VMs; comin auto-deploys from Codeberginfrastructure
PlatformShared identity, secrets, storage, CI, chat bridges, observabilityobservability, keycloak-theme
DeployBranch-based preview and production deploys via Nix buildskennel, devenv
ApplicationsProduct repos deployed through Kennel when kennel = true in governanceSee team pages under Projects

Hosts

HostPurpose
infra-01Tailscale client; Caddy → public platform services; Headscale server + Headplane; Headscale → Caddy → pgAdmin (tailnet); Prometheus scraper + Grafana/Loki/Tempo
deploy-01Tailscale client; Caddy → kennel → Kennel deployments; Headscale → Caddy → pgAdmin (tailnet); internet-archive batch job
snoopyTailscale client + host exporters (scraped by Prometheus on infra-01)
bus-sign-displayOn-prem display for the bus-sign project

Teams and repos

Registered in governance under data/teams/:

TeamRepos
DevOpsinfrastructure, governance, kennel, devenv, observability, documentation
CMU Coursescourses, internet-archive
CMU Housinghousing
Tartan Votetartan-vote
Questquest
SLAIcmugpt-surface, cmugpt-agent, mcp-server, sms-surface
CBPbus-sign, dalmatian, discord-verify, groupme-mirror
UI Architecturecomponents