The agent

Optional. A small service on your own hardware that keeps watching when your phone is asleep.

On this page

Whether you need one

The app is complete without it. Every server, every reading and every control works with nothing but the phone. The agent exists for the things a phone genuinely cannot do: keep polling while it is in your pocket, hold more than a few hours of history, and send you a notification from hardware you own rather than from a service you don't.

It runs the app's own adapters — the same source files, compiled into a single binary. That is the point rather than an implementation detail: an agent that graded a problem differently from the phone would be worse than no agent, because you would stop trusting both. The thresholds, the concern rules and the wording come from one place.

Installing it

It belongs in a container of its own — an LXC, a small VM, a Pi, or Docker. That is not fussiness: trusting a server's certificate is system-wide on the machine that does it, so the blast radius should be one box that does nothing else.

The quickest path on a Debian LXC or VM is one file and one script:

scp install.sh homelab-deck-agent.service root@AGENT-BOX:/tmp/
ssh root@AGENT-BOX "bash /tmp/install.sh --binary /tmp/agent"

Or with Docker, on a TrueNAS app, Unraid, Synology or any Docker host:

docker run -d --name homelab-deck-agent \
  -v /etc/homelab-deck:/etc/homelab-deck \
  -p 8787:8787 \
  ghcr.io/lhend941/homelab-deck-agent

Building it yourself, the systemd unit and the full configuration reference live in the agent's own README, which ships with it.

Pairing your phone

Run this once on the agent's box. It writes the config, turns TLS on, and prints the token the phone needs:

homelab-deck-agent pair
It will not overwrite anything. If a config already exists, pair prints the existing token and changes nothing — so it is also the safe way to look the token up later.

Then, in the app, Settings → Alerts → Agent: enter the agent's address and port (8787 by default) and the pairing token.

Address the agent the way its certificate names it. pair issues a certificate for the box's own address, so if that is an IP, use the IP — the opposite of the advice for your servers, and correct for the same reason: the name you dial has to be the name on the certificate. The app shows you the fingerprint on first connect. Compare it against the agent's own:

homelab-deck-agent fingerprint

Letting the phone send its servers

Pairing alone lets the app read the fleet. Sending the phone's server list to the agent needs a second token, because reading what the agent sees and rewriting what it watches are very different powers and should not travel on the same string:

homelab-deck-agent write-token

That prints the existing token, or mints one the first time. Enter it in the same screen. Without it the agent refuses changes outright, which is the default on purpose.

Don't pass --new unless you mean it. It replaces the write token, and every phone holding the old one loses the ability to change anything.

Pairing again after a new or reset phone

Nothing on the agent needs recreating. A new phone, a reset one, or a reinstalled app all land in the same place, and both tokens are still sitting in the agent's config:

homelab-deck-agent pair          # prints the existing pairing token
homelab-deck-agent write-token   # prints the existing write token
homelab-deck-agent fingerprint   # to compare when the app asks

Enter those three in Settings → Alerts → Agent as before. Don't run pair expecting a fresh token and don't add --new: both of those are for replacing a token you believe has leaked, not for setting up a phone.

A reset phone does not get your credentials back from the agent. There is deliberately no way to ask the agent for them: an endpoint that served every credential to anything holding the pairing token would make that token equivalent to full access on every server you own. The way across is the app's own encrypted backup, made before you need it. Without one, a rebuilt phone means new API tokens on each server.

Servers the agent already watches

A server the agent knows about but the phone doesn't appears on the fleet screen under Watched by your agent, read-only, because the app holds no credential for it. Adopt it rather than adding it again — adopting carries the agent's own identifier across, which is what keeps one machine as one card.

Removing one

A server the agent watches cannot be deleted from the phone, and that is not an oversight: the agent's config file is mounted read-only to the service, so it cannot rewrite the file holding its own credentials. Remove it where it is defined — the hosts list in /etc/homelab-deck/config.json, then restart the agent, or on the phone that synced it.

Certificates

Two separate things, and they are easy to confuse.

The agent's own certificate is the one your phone approves when you pair, covered above.

Your servers' certificates are the thing most likely to stop the agent working, because almost every homelab box ships a self-signed one. The agent validates certificates like any other client and will not skip the check, so out of the box it cannot talk to a default Proxmox or TrueNAS over HTTPS. Trust each server once, on the agent's machine:

homelab-deck-agent trust 10.0.0.20:8006

It fetches the certificate, shows you its subject, issuer and SHA-256 fingerprint, and asks you to confirm — the same trust-on-first-use the app does, with the approval at a prompt instead. Any mismatch refuses outright and changes nothing.

Trusting cannot fix a certificate that names something else. A certificate issued for localhost cannot validate a connection to 10.0.0.50, however much you trust it — and TrueNAS's default certificate is exactly this. Either give that server a certificate naming the address you use, or watch it directly from the app, which approves a fingerprint by hand.

What it deliberately can't do

Questions about any of this: [email protected].