Skip to main content

Homelab Otel

@figy/homelab-otelv2026.10.05.1beta· 19d agoBEHAVIORSWORKFLOWS
01README

Site-specific OpenTelemetry bootstrap for the fi.gy homelab — my domains, meshes, and tiers, wired into four workflows. WHAT IT DOES

The concrete, private half of an OpenTelemetry fleet setup. It supplies my observability contract — the dedicated otel.fi.gy sub-zone, the tailscale and wireguard gateway endpoints, home/sven attributes, and 14/90/7-day retention — to the generic @svendowideit models, and runs the whole publish path: render the contract, stage it versioned, serve it over HTTP(S) at settings.otel.fi.gy, proxy the OpenObserve UI at obs.otel.fi.gy, terminate TLS for the OTLP endpoint at otlp.fi.gy, reconcile the DNS records, and verify the live document. One @svendowideit/caddy model (otel-caddy) owns all otel Caddy config — records, wildcard TLS, and the settings, store-UI and OTLP routes. Prefer it over hand-editing settings on each host: change the contract once and every agent fetches it. This is site-specific by design — it encodes my domains, meshes, and gear, so it is useless without them; the portable model types live in @svendowideit.

INSTALL

swamp extension pull @figy/homelab-otel

DEPENDENCIES

@svendowideit/otel-settings, @svendowideit/otel-agent, @svendowideit/settings-server, @svendowideit/caddy, @svendowideit/otel-backend, @svendowideit/otel-gateway, @svendowideit/openobserve, and @svendowideit/fleet-inventory — pulled separately. A figy-trusted swamp repo (swamp extension trust add figy) so the pull resolves.

Docker, plus the store's admin login in a vault BEFORE running the backend bootstrap. The OpenObserve profile seeds its first admin user at first start, so both keys must exist or the container crash-loops:

swamp vault create @svendowideit/systemd-creds otel-openobserve-admin
swamp vault put otel-openobserve-admin ZO_ROOT_USER_EMAIL
swamp vault put otel-openobserve-admin ZO_ROOT_USER_PASSWORD

RUN

# Store the store's admin login first (the backend seeds it on first start).
swamp vault create @svendowideit/systemd-creds otel-openobserve-admin
swamp vault put otel-openobserve-admin ZO_ROOT_USER_EMAIL
swamp vault put otel-openobserve-admin ZO_ROOT_USER_PASSWORD

# Render, stage, serve, and verify the fi.gy observability contract.
swamp workflow run @figy/homelab-otel-bootstrap

Bring up the whole core node: store + gateway + DNS + TLS + named UI.

swamp workflow run @figy/bootstrap-otel-backend

Onboard a managed Debian/Ubuntu host onto the core node (Phase 2).

swamp workflow run @figy/host-onboard

Run this repo as an always-on swamp serve at swamp.x1yoga.fi.gy and

dashboard.x1yoga.fi.gy (dashboard + hot-reload + auto-resume on), with its

own telemetry pointed at the otel.fi.gy gateway.

swamp workflow run @figy/swamp-serve-bootstrap

Read the resolved contract for scripting.

swamp data get otel resolved --json

# Fetch the served machine contract.
curl https://settings.otel.fi.gy/otel.json

# Open the store UI (proxied by Caddy with the wildcard cert).
curl -I https://obs.otel.fi.gy/

# Confirm the public OTLP/HTTP endpoint terminates TLS (the gateway's own
# receiver is plaintext; Caddy terminates TLS on 443 for these agents).
curl -sI https://otlp.fi.gy/v1/logs

CONFIGURE

Each workflow takes optional --input overrides, so the same definitions run in each environment:

deploymentEnvironment   dev (this machine) | uat (T440s) | prod (Xeon)
settingsHostname        defaults to settings.otel.fi.gy
webroot                 directory Caddy serves the staged bundle from
bindAddress             address the store/gateway bind to (127.0.0.1 or a mesh address)
vaultName               vault holding the OpenObserve admin login
caddyModelName          Caddy model for the serve hostnames (default my-caddy)
otelSettingsModel       otel-settings model for the serve telemetry (default otel)

The site values themselves (domain, endpoints, meshes, retention) are fixed in the workflows' step globalArgs, because they are the point of this extension.

The @figy/homelab-otel model's only global arg is deploymentEnvironment (dev | uat | prod); homelab-otel describe emits the topology for it.

WHAT IT INSTALLS

It creates/updates swamp models and data; via @svendowideit/caddy it adds the settings route at settings.otel.fi.gy, and @figy/swamp-serve-bootstrap (via @svendowideit/swamp-serve and @svendowideit/systemd-service) installs a systemd user service running swamp serve, with Caddy routes and DNS for swamp.x1yoga.fi.gy and dashboard.x1yoga.fi.gy. No cron triggers or webhooks.

02Behaviors1
@figy/homelab-otelv2026.10.05.1homelab_otel.ts

Global Arguments

ArgumentTypeDescription
deploymentEnvironmentenumWhich environment this catalog describes
fn describe()
Emit the site topology (zone, DNS records, endpoints, hosts) as a resource

Resources

topology(infinite)— The fi.gy observability topology
03Workflows4
@figy/homelab-otel-bootstrap1c7e6263-a926-43c2-b7bb-399a0afe348c

@figy site-specific OTel bootstrap for the fi.gy homelab. Renders my observability contract under the dedicated `otel.fi.gy` sub-zone, stages it, serves it over HTTP(S) at `settings.otel.fi.gy` by Caddy (DNS-01 TLS via Gandi), and verifies the live document. The site-specific values (domains, meshes, tiers) live in the step globalArgs below, so a pull of @figy/homelab-otel plus a run creates the models in place. Usage: swamp workflow run @figy/homelab-otel-bootstrap Then read the contract a

mainRender, publish, serve, and verify the fi.gy observability contract.
1.render-settings— Resolve the fi.gy contract and write the HTTP document set.
2.publish-bundle— Stage the rendered documents into the webroot and flip current.
3.mirror-agent— Mirror the pinned otelcol-contrib release onto the settings server.
4.serve-settings— Serve the webroot at settings.otel.fi.gy via Caddy file_server.
5.configure-tls— Configure otel-caddy's wildcard *.otel.fi.gy TLS (Gandi DNS-01).
6.reconcile-records— Reconcile the otel/otlp/settings/obs DNS records.
7.verify-settings— Fetch the live index document to prove the URL works.
@figy/bootstrap-otel-backend477b856a-8f92-4a48-82ac-40504cd5b7df

@figy site-specific OpenTelemetry backend bootstrap for the fi.gy homelab: bring up the whole core node in one run — the OpenObserve store, the collector gateway that fans out to it, the DNS records for the otel.fi.gy names, and a synthetic OTLP push that proves the pipeline end-to-end. This is the Phase 1 core-node build. It is the concrete half of the generic @svendowideit extensions: the store and gateway profiles are portable, but the fi.gy names, the Gandi provider, and the vault holding t

coreBuild and verify the fi.gy OTel core node.
1.topology— Emit the fi.gy topology (zone, records, endpoints, hosts).
2.render-settings— Resolve the fi.gy contract and write the HTTP document set.
3.publish-settings— Stage the rendered documents into the Caddy-served webroot.
4.mirror-agent— Mirror the pinned otelcol-contrib release onto the settings server.
5.backend— Start the OpenObserve store with its admin login from the vault.
6.gateway— Start the collector, exporting to the backend with vault Basic auth.
7.otel-caddy-tls— Configure otel-caddy's TLS (wildcard *.otel.fi.gy via Gandi DNS-01).
8.otel-caddy-settings-route— Serve the settings webroot at settings.otel.fi.gy via file_server.
9.otel-caddy-store-ui— Proxy obs.otel.fi.gy to the OpenObserve UI.
10.otel-caddy-otlp-route— Terminate TLS for otlp.fi.gy on Caddy's 443 and reverse-proxy it to the gateway's plaintext OTLP/HTTP receiver. The gateway's receiver is plaintext (4318) and cannot share the TLS port, so the public OTLP/HTTP URL is https://otlp.fi.gy (no port) while local agents keep :4318.
11.otel-caddy-records— Reconcile the otel/otlp/settings/obs records via Caddy dns_records.
12.verify-push— Push a synthetic OTLP record through the gateway.
13.verify-query— Query the synthetic record back from OpenObserve with SQL.
14.verify-ui— Assert otel-caddy's desired state carries every route and record this workflow asks it to reconcile. caddy persists its state under the 'desired' instance (one resource the reconcile reads), not under a per-method spec name, so the assertion reads that resource.
@figy/host-onboarde7dcd3a5-d0de-4cc6-b0c3-afb4214cfad8

@figy host onboarding: bring one or more managed Debian/Ubuntu hosts under telemetry — install the OTLP agent from the published settings contract, reconcile their DNS records, and confirm they report. This is the incremental fleet rollout: onboard a host, confirm it appears in the store, then move to the next. The agent fan-out supports many hosts at once, but the operating target is deliberately small until it is trusted. It reads the host list from the fleet inventory (managed, non-silent-r

onboardInstall the agent, reconcile records, and confirm reporting.
1.inventory— Read the fleet inventory to pick managed Debian/Ubuntu hosts.
2.install-agent— Install the OTLP agent on the selected hosts (fan-out).
verifyConfirm the just-onboarded hosts appear in the store.
1.reporting-hosts— Query OpenObserve for the host names currently reporting.
@figy/swamp-serve-bootstrapdd3b4faa-b45d-4414-9e92-2643525d1621

@figy site-specific setup: run this swamp repository as an always-on `swamp serve` on the fi.gy homelab, reachable at swamp.x1yoga.fi.gy and dashboard.x1yoga.fi.gy with the dashboard, hot-reload and auto-resume on. This is the concrete half of @svendowideit/swamp-serve. The generic model is portable; the names and models here are mine. During development the base domain comes from the `my-caddy` model (which already owns x1yoga.fi.gy → 10.10.13.208), so the two hostnames derive automatically. W

serveResolve, install, configure, serve, expose, observe.
1.resolve— Derive swamp.x1yoga.fi.gy and dashboard.x1yoga.fi.gy from my-caddy before anything is written, so the hostnames can be inspected first.
2.install— Install the swamp binary only if it is absent; a present binary is left for the model's updateBinary method to upgrade.
3.configure— Write .swamp/serve.yaml with the dashboard, hot-reload and auto-resume enabled, and validate it with `swamp serve check-config`.
4.service— Create and start the systemd user unit; this is the point the server runs and the dashboard becomes reachable on the bound port.
5.configure-caddy— Declare the two A records and TLS subjects on the Caddy model itself. A Caddy model reconciles only its own dnsRecords and TLS subjects, so the site must add them here; the hostnames come from the resolve step.
6.dns— Apply the Caddy model's declared records (including the two just added) so both hostnames resolve. Allowed to fail so the service still comes up if the Caddy model is absent.
7.verify-dns— Verify the Caddy model now owns both A records (reports anything missing rather than fabricating a record it cannot persist).
8.proxy— Reverse-proxy both hostnames to the server through my-caddy, which also issues their TLS certificates. Fails softly with the DNS step.
9.telemetry— Apply the OTLP environment from the `otel` contract so the server's logs, metrics and traces reach the fi.gy gateway. Skipped cleanly when the contract has not been rendered yet.
10.status— Report the final state: systemd active, HTTP status of both hostnames, the swamp version, and the telemetry summary.
04Previous Versions3
2026.10.04.2

Added 1 workflows. updated dependencies

2026.10.04.1

Added 1 workflows. updated dependencies

2026.10.03.1
05Stats
A
93 / 100
Downloads
2
Archive size
18.2 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License1/2partial

    no SPDX license declared

  • Verified public repository2/2earned
06Platforms