Meet Bob: a tiny “Basic Orchestration Bot” for the homelab
Around here, Bob is less a single binary and more a name for orchestration: one small service that speaks Portainer, plus a Node-RED side that runs the daily briefing and a few other gentle automations. There is no public repository to link — this is a friendly overview of how that fits together.
The infra piece
Bob (the service) is a compact TypeScript app that asks Portainer what is running across your Docker endpoints and returns a single JSON document your dashboards and scripts can consume. No UI, no database — just Express, fetch, and the Portainer API.
Portainer already lists containers. What this layer adds is a normalized view: every row knows which environment it belongs to, what image it runs, current state, useful labels, and a guess at a browser URL (http://host:lowest-published-tcp-port) when Docker publishes TCP ports. That keeps status boards and launcher pages simple without scraping the Portainer UI.
Endpoints: GET / is a plain-text sanity check; GET /api/infra/apps returns envs plus a flattened apps list (env, name, url, state, image, id, labels). The process listens on PORT or 9001 by default — intentionally not the usual Portainer port (often 9000) so you are less likely to confuse “wrong service” with “Bob crashed.”
Under the hood it uses POST /api/auth against Portainer (JWT cached, refresh on 401), /api/endpoints for environments and hosts, then Docker’s /containers/json via Portainer’s proxy. If you see a bare Cannot GET /api/infra/apps on port 9000, you are probably talking to Portainer — Bob’s own 404 returns JSON { "error": "Not found" }.
Node-RED: the daily briefing “Bob”
Separately, Node-RED carries the workflows we still call Bob in conversation: a daily briefing that nudges habits (things like vitamins, a walk, reading, gym), surfaces upcoming events from a Notion calendar feed, and mentions public holidays so the day does not surprise you. It is the same spirit as the infra bot — reduce friction — but aimed at routine and context, not containers.
We are also preparing a personal finance setup to help track expenses; that will fold into the same “know what your day and money story looks like” picture over time.
Finally, another Node-RED flow watches RSS and sends a Telegram message when a new episode lands — small delight, no staring at feeds.
Bob stays deliberately human-scale: one clear JSON surface for machines, and automation that respects attention for everything else.
