Skip to content

Docs

Monitor agent

The Monitor agent watches services the public internet cannot reach: internal APIs, databases, admin panels, anything behind your firewall or inside your VPC. It runs on a server you own, pulls its checks from RealUptime, runs them from inside your network, and posts the results back. It also reports the health of the machine it runs on, so a server has charts and history without a second agent to install.

Register an agent

From Monitor settings in the dashboard, choose Register agent and give it a name. The token is shown once, at creation, alongside the exact install command with that token already filled in. If you lose the token, revoke it and register a new one: tokens are stored hashed, so nobody at RealUptime can read yours back to you.

Install

Docker, one command:

docker run -d --name realuptime-agent --restart unless-stopped \
  -e REALUPTIME_TOKEN=rua_your_token_here \
  ghcr.io/realuptimehq/agent:latest

Docker Compose:

services:
  realuptime-agent:
    image: ghcr.io/realuptimehq/agent:latest
    restart: unless-stopped
    environment:
      REALUPTIME_TOKEN: rua_your_token_here

Without Docker

Node.js 22 or newer:

bash
pnpm install
pnpm --filter @realuptime/agent build
REALUPTIME_TOKEN=rua_your_token_here node dist/agent.js

Run it under whatever supervisor you already use. A minimal systemd unit:

[Unit]
Description=RealUptime Monitor agent
After=network-online.target

[Service]
ExecStart=/usr/bin/node /opt/realuptime-agent/dist/agent.js
Environment=REALUPTIME_TOKEN=rua_your_token_here
Restart=always
RestartSec=10
User=realuptime
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true

[Install]
WantedBy=multi-user.target

The hardening directives in that unit are safe to keep. The agent writes nothing to disk.

Verify the image

Published images are signed with cosign, using a key pair generated for this purpose rather than GitHub's keyless OIDC flow: this image is built and published from operator hardware, not a GitHub Actions runner, so there is no OIDC token for cosign to use. Each build also carries a software bill of materials (SPDX, generated with syft) and a provenance record naming the builder, the git commit, and the build time, attached to the same image as signed attestations.

Verify a pulled image against the public key this site serves:

bash
cosign verify --key https://realuptime.io/.well-known/cosign.pub \
  ghcr.io/realuptimehq/agent:latest

Check the software bill of materials the same way:

bash
cosign verify-attestation --key https://realuptime.io/.well-known/cosign.pub \
  --type spdxjson ghcr.io/realuptimehq/agent:latest

The public key lives at a stable address, realuptime.io/.well-known/cosign.pub, not a page-specific download link, so a script can fetch it the same way every time. Signing rolls out with the image's first signed release: an image published before that date has no signature to check, and cosign verify failing against an older pull means exactly that, not a broken install.

Configuration

Two environment variables. There are no others, no flags, and no config file.

VariableRequiredDefaultPurpose
REALUPTIME_TOKENYesnoneThe agent token from the dashboard.
REALUPTIME_URLNohttps://realuptime.ioOverride only for a self-hosted or staging deployment.

A missing token is the only condition that stops the agent. Everything else, including a rejected token, is retried indefinitely.

Outbound only

The agent opens outbound HTTPS on port 443 to one hostname, and nothing else. It opens no inbound port: nothing can connect to it, and there is no listening socket to expose, scan, or firewall. It executes no commands: there is no shell out, no exec, no remote command channel. RealUptime can tell it which addresses to check and how often, and nothing else. There is nothing in this program by which RealUptime, or anyone who compromised RealUptime, could run anything on your machine.

It reads no configuration file, no credentials, and none of your data. For an HTTP check it reads the status line and immediately aborts the response body, never buffering, inspecting, or logging it. A TCP check writes nothing to the socket and reads nothing from it. A DNS check reads only the records it queried for.

If you run it inside a container

If the agent itself runs inside a container, its server-health metrics describe the container, not the underlying host, and RealUptime records them that way: this is a real, useful thing to monitor, not a limitation to work around. CPU, memory, and disk figures then reflect the container's own resource limits, which can be very different from the host machine's. The vantage a token first reports under is pinned: if the agent later reports a different vantage on the same token (moved from a container to the host, or back), RealUptime refuses the batch rather than silently mixing a different kind of reading into the same history. Register a new agent token for the new vantage instead.

If your goal is host-local targets, services bound to localhost or a host-only interface, or you want the machine's own CPU, memory, and disk rather than the container's, run the agent with host networking, or directly on the host, not inside an isolated container.

What data is collected

Once a minute the agent reads a handful of files the Linux kernel exposes about the machine it runs on and posts one sample.

FieldUnitSource
CPU usedfraction of total capacity across all cores, 0 to 1/proc/stat, delta between two readings
Memory usedbytes, total minus available (not minus free)/proc/meminfo
Disk usedbytes, per mounted filesystem, up to 32/proc/mounts plus a statvfs reading
Load averageraw 1/5/15 minute kernel averages, not normalized by core count/proc/loadavg

Each check result the agent sends is a check id, up or down, an HTTP status code where there is one, a latency in milliseconds, an error string when the check failed, and the timestamp of the observation. Nothing about a machine's process list, file listing, or their contents is ever sent. See server health for what the charts built from this data show, and when they alert you.