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:latestDocker Compose:
services:
realuptime-agent:
image: ghcr.io/realuptimehq/agent:latest
restart: unless-stopped
environment:
REALUPTIME_TOKEN: rua_your_token_hereWithout Docker
Node.js 22 or newer:
pnpm install
pnpm --filter @realuptime/agent build
REALUPTIME_TOKEN=rua_your_token_here node dist/agent.jsRun 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.targetThe 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:
cosign verify --key https://realuptime.io/.well-known/cosign.pub \
ghcr.io/realuptimehq/agent:latestCheck the software bill of materials the same way:
cosign verify-attestation --key https://realuptime.io/.well-known/cosign.pub \
--type spdxjson ghcr.io/realuptimehq/agent:latestThe 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.
| Variable | Required | Default | Purpose |
|---|---|---|---|
REALUPTIME_TOKEN | Yes | none | The agent token from the dashboard. |
REALUPTIME_URL | No | https://realuptime.io | Override 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.
| Field | Unit | Source |
|---|---|---|
| CPU used | fraction of total capacity across all cores, 0 to 1 | /proc/stat, delta between two readings |
| Memory used | bytes, total minus available (not minus free) | /proc/meminfo |
| Disk used | bytes, per mounted filesystem, up to 32 | /proc/mounts plus a statvfs reading |
| Load average | raw 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.