Skip to content

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:

  1. The bootstrap .deb writes /etc/apt/sources.list.d/openremedy.list pointing at https://dls.openremedy.io/apt/, plus the GPG keyring at /usr/share/keyrings/openremedy-archive-keyring.gpg.
  2. apt update pulls the OpenRemedy package index.
  3. apt install lays down the binary, config, systemd unit, and sudoers drop-in. The post-install script creates the openremedy-client system user and adds it to the docker group (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:

  1. Open the dashboard → ServersAdd server.
  2. Give the server a hostname / role / labels.
  3. 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:

sudo systemctl enable --now openremedy-client.service

On first start the daemon:

  1. Reads config.json.
  2. 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.
  3. POSTs /daemon/v1/register to the platform with hostname, IP, client version, and fingerprint.
  4. Receives a server_id and a session_token in the response; persists both in state.json.
  5. 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

sudo apt update && sudo apt install --only-upgrade openremedy-client

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

sudo apt remove --purge openremedy-client

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"

groups openremedy-client
# → openremedy-client docker     ← docker must be in the list

If docker is missing, the postinst hook either ran before Docker was installed or the group didn't exist. Fix:

sudo usermod -aG docker openremedy-client
sudo systemctl restart openremedy-client

"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:

curl http://127.0.0.1:9201/metrics | grep openremedy_client_self

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