Daemon install¶
The OpenRemedy client daemon (openremedy-client) is a small Go
binary that runs as a systemd service on every Linux host you want
the platform to manage. It registers with the platform once,
heartbeats every 30 seconds, runs the monitors the platform tells
it to, and pushes evidence back.
This page covers installing and registering the daemon. For tunable config and runtime details, see configuration.
Supported platforms¶
| OS | Architecture | Package |
|---|---|---|
| Debian 12 / 13, Ubuntu 22.04 / 24.04 | amd64, arm64 |
.deb from the OpenRemedy APT repo |
| RHEL / Fedora / Alpine | amd64, arm64 |
binary tarball from GitHub Releases (manual install) |
The systemd unit shipped in the .deb assumes systemd as the init
system. Hosts using OpenRC, runit, etc. need a hand-written service
file; the binary itself runs anywhere.
Quick install (Debian / Ubuntu)¶
Two lines:
curl -fsSL https://dls.openremedy.io/openremedy-repo.deb -o /tmp/openremedy-repo.deb
sudo dpkg -i /tmp/openremedy-repo.deb
sudo apt update && sudo apt install -y openremedy-client
What this does:
- The bootstrap
.debwrites/etc/apt/sources.list.d/openremedy.listpointing athttps://dls.openremedy.io/apt/, plus the GPG keyring at/usr/share/keyrings/openremedy-archive-keyring.gpg. apt updatepulls the OpenRemedy package index.apt installlays down the binary, config, systemd unit, and sudoers drop-in. The post-install script creates theopenremedy-clientsystem user and adds it to thedockergroup (idempotent — silent if Docker isn't installed).
The daemon does not start automatically. It needs a server token first.
Manual install (other distros)¶
Download the binary and packaging assets from the latest GitHub Release:
https://github.com/OpenRemedy/openremedy-client/releases
Assets per release: .deb (amd64 + arm64) and a .tar.gz with the
raw binary. For non-Debian systems, extract the tar, drop the binary
in /usr/local/bin/, and write your own systemd unit / OpenRC
service. The unit shipped in the .deb is a good template — install
the .deb on a throwaway VM and cat /lib/systemd/system/openremedy-client.service.
What gets installed¶
| Path | Purpose |
|---|---|
/usr/local/bin/openremedy-client |
The binary. |
/etc/openremedy-client/config.json |
Runtime config (mode 0600). |
/etc/openremedy-client/state.json |
Persisted registration state (mode 0600). Created on first registration. |
/lib/systemd/system/openremedy-client.service |
The systemd unit. |
/etc/sudoers.d/openremedy-client |
NOPASSWD sudo rules for the daemon's allowed commands. |
/var/lib/openremedy-client/ |
Working directory (the daemon's $HOME). Holds the tasks cache. |
The daemon runs as the system user openremedy-client. It is added
to the docker group at install so it can run docker ps for
discovery without sudo.
Registering with the platform¶
Generate a server token in the dashboard:
- Open the dashboard → Servers → Add server.
- Give the server a hostname / role / labels.
- Copy the one-time token (format
orem_srv_…).
On the host:
sudo openremedy-client --init \
--platform-url https://app.example.com \
--token orem_srv_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
--init writes config.json with the platform URL + token and exits.
Then enable + start the service:
On first start the daemon:
- Reads
config.json. - Computes a host fingerprint (a hash of DMI UUID, machine-id, and root filesystem UUID) — used by the platform to detect token theft across machines.
- POSTs
/daemon/v1/registerto the platform with hostname, IP, client version, and fingerprint. - Receives a
server_idand asession_tokenin the response; persists both instate.json. - Starts the heartbeat / evidence / task-poll loops.
Subsequent restarts skip step 3 — the daemon reuses the registered
state. Delete state.json to force re-registration (e.g. after a
host re-image).
Verifying the install¶
Three checks, in order. If any fails, jump to troubleshooting below.
# 1. Is the service running?
systemctl status openremedy-client.service
# 2. Is the local API responding?
curl -fsS http://127.0.0.1:9201/healthz | jq .
# → {"status":"ok", "uptime_seconds": ..., "last_heartbeat_at": ...}
# 3. Did the platform see it?
# In the dashboard, the server should turn green within 60 seconds
# of the systemctl start.
Discovery¶
Once the daemon is up, it auto-discovers what's running on the host and reports it back every five evidence cycles (~5 minutes by default). The platform uses discovery output to populate the Servers → Workloads view.
| What | How |
|---|---|
| Docker containers | docker ps (daemon must be in docker group; postinst handles this). |
| systemd services | systemctl list-units --type=service --state=active. |
| Listening ports + owning process | ss -tlnp (requires iproute2; install if missing). |
| Disk mounts | df filtered to non-tmpfs mounts. |
Failures are silent — a missing docker binary doesn't break
discovery, the container list just comes back empty.
Upgrading¶
The post-install script restarts the daemon. State (server_id,
session_token, fingerprint) is preserved across upgrades; you do
not need to re-register.
Uninstalling¶
Removes the binary, unit file, and config. The daemon's state file
under /etc/openremedy-client/ is also removed by --purge. The
server row stays in the platform's database; deregister it via the
dashboard's Servers → Remove action if you don't plan to
re-attach.
Troubleshooting¶
"Daemon registered but no heartbeats reaching the platform"¶
sudo journalctl -u openremedy-client.service -n 100 --no-pager
curl http://127.0.0.1:9201/healthz # local view
If the local /healthz says degraded, the daemon hasn't reached
the platform recently — typically a network egress or TLS issue.
Confirm curl -fsS https://app.example.com/health works from the
host first.
"Custom monitors aren't running"¶
Custom monitors require the platform to HMAC-sign the command (the daemon refuses unsigned ones). This was added in client v0.2.0. If you see HTTP 426 from the platform's task endpoint, your daemon is older than the gate; upgrade.
"Docker discovery returns empty"¶
If docker is missing, the postinst hook either ran before Docker
was installed or the group didn't exist. Fix:
"Fingerprint degraded"¶
On startup the daemon logs a warning if any of the three fingerprint
sources (DMI UUID, machine-id, root FS UUID) are unreadable. Common
in containers — DMI isn't exposed. The daemon proceeds with a weaker
fingerprint; the platform will still accept heartbeats but the
token-theft detection is less precise. On bare metal, investigate
why /sys/class/dmi/ or /etc/machine-id is missing.
"Daemon CPU or memory is climbing"¶
Query the local metrics endpoint:
Each monitor adds runtime cost; the platform might have given this host more monitors than it can handle. Check the alert policies attached to the server and prune.
See also¶
- Daemon configuration — every config field and what it controls.
- Architecture: daemon flow — what's on the wire between the daemon and the platform.
- Security — token, session, fingerprint, HMAC custom-monitor signing.