Skip to content
StatusTick

Private agents

Run the StatusTick private agent inside your network: install with Docker or Helm, settings, check types, proxy, offline buffer, relay, metrics and updates.

Updated 14 Oct 2026

The agent runs inside your network and checks what StatusTick's public locations can't reach. A private location is a group of agents that share its checks and take over when one stops. Each agent connects out to agent.statustick.com:443 with its own token; nothing connects to the agent.

Install

In StatusTick, open the private location, choose Add agent and run the install command it shows. The token is shown once and belongs to one machine: if two machines use it, the newer one wins.

Docker

docker run -d --name statustick-agent --restart unless-stopped --shm-size 512m \
  --cap-drop ALL --cap-add SETUID --cap-add SETGID \
  -e STATUSTICK_TOKEN="sta_live_…" \
  -e STATUSTICK_INSTALL=docker \
  ghcr.io/statustick/agent:1

With Docker Compose:

services:
  statustick-agent:
    image: ghcr.io/statustick/agent:1
    restart: unless-stopped
    environment:
      STATUSTICK_TOKEN: "sta_live_…"
      STATUSTICK_INSTALL: compose
    shm_size: 512m
    cap_drop: [ALL]
    cap_add: [SETUID, SETGID]

The image (about 330 MB) runs every check type, browser checks included. Chromium needs --shm-size 512m; SETUID and SETGID let each browser check run as its own user. The agent runs as user 10001 and works with --read-only --tmpfs /tmp.

Binary

The static Linux binary (amd64, arm64) runs everything except browser checks. Download it from a release, check it against SHA256SUMS, and run it as a service:

sudo install -m 0755 statustick-agent /usr/local/bin/statustick-agent
sudo useradd --system --no-create-home --shell /usr/sbin/nologin statustick
sudo install -d -o statustick -m 0700 /var/lib/statustick
sudo install -m 0600 /dev/null /etc/statustick-agent.env
echo 'STATUSTICK_TOKEN=sta_live_…' | sudo tee /etc/statustick-agent.env >/dev/null
sudo tee /etc/systemd/system/statustick-agent.service >/dev/null <<'UNIT'
[Unit]
Description=StatusTick agent
After=network-online.target
Wants=network-online.target

[Service]
User=statustick
EnvironmentFile=/etc/statustick-agent.env
Environment=STATUSTICK_INSTALL=other STATUSTICK_BUFFER_DIR=/var/lib/statustick
ExecStart=/usr/local/bin/statustick-agent
Restart=always
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/statustick

[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload && sudo systemctl enable --now statustick-agent

Kubernetes

Use the Helm chart; one release is one agent.

Settings

VariableTypeDefaultValuesWhat it does
STATUSTICK_TOKENtextnone (required)anyThe agent's token, from its page in StatusTick.
STATUSTICK_URLURLhttps://agent.statustick.comhttps; http for localhost, *.localhost and 127.0.0.1Where the agent connects.
STATUSTICK_CONCURRENCYwhole number51 to 50Checks at the same time. Overrides "Max checks" in the dashboard.
STATUSTICK_ALLOWlistnoneaddress ranges, single addresses, host names and *. subdomain wildcards, for example 10.0.0.0/8,192.168.1.20,*.corp.exampleOnly check these targets; others fail without being tried. See "Target rules".
STATUSTICK_HOSTNAMEtextthe container's host nameanyThe host name shown on the agent's page.
STATUSTICK_INSTALLchoiceset by the install command or the chartdocker, compose, helm or otherHow the agent was installed, shown on its page. Detected when unset.
HTTPS_PROXYURLnonehttp://host:port or https://host:port, with user:password@ for basic authenticationProxy for StatusTick and HTTPS checks. Falls back to HTTP_PROXY.
HTTP_PROXYURLnoneas HTTPS_PROXYProxy for plain http checks.
NO_PROXYlistnonedb.internal, .corp (the domain and its subdomains), host:8443 (that port only), IP addresses, CIDR ranges such as 10.0.0.0/8, or * for allHosts that skip the proxy.
NODE_EXTRA_CA_CERTSpathnonea PEM fileExtra CA certificates to trust, such as your proxy's or internal CA.
STATUSTICK_BUFFER_SIZEwhole number100001 to 100000Results kept while StatusTick is unreachable. The oldest are dropped when full.
STATUSTICK_BUFFER_DIRpathnone (memory only)a writable folderKeeps the buffer across restarts. The agent stops if it can't write here.
STATUSTICK_HEALTH_PORTportnone (no port)1 to 65535Serves /healthz and /readyz for Kubernetes probes. The chart sets 8080.
STATUSTICK_RELAY_PORTportnone (no port)1 to 65535, not the health portOpens the heartbeat relay. Internal only; never expose it. See "Heartbeat relay".
STATUSTICK_RELAY_HOSTIP address0.0.0.0an address of this hostAddress the relay listens on. Use the internal one on multi-network hosts.
STATUSTICK_DISCOVERYchoicenone (off)kubernetesCreates monitors from annotated Kubernetes Services. See "Kubernetes service discovery".
STATUSTICK_DISCOVERY_NAMESPACESlistnone (every namespace)namespaces, for example shop,paymentsNamespaces to watch.
METRICS_PORTportnone (no port)1 to 65535, not the health or relay portServes Prometheus /metrics. See "Metrics".
METRICS_HOSTIP address0.0.0.0an address of this hostAddress the metrics port listens on.
STATUSTICK_SHARE_METRICSchoicenone (follows the dashboard)true or falseShare the agent's health with StatusTick. Unset follows the dashboard.
BROWSER_CONCURRENCYwhole number10 to 8Browser checks only. Browser checks at the same time; 0 turns them off. Each needs up to 2 GB.
STATUSTICK_BROWSER_ISOLATIONchoicenone (isolated when the container allows it)user or offRun each browser check as its own user. user requires it; off disables it.
STATUSTICK_REQUIRE_SECRET_HOSTSchoicenonetrueRefuse secrets that have no _HOSTS list.
STATUSTICK_SECRET_<NAME>_HOSTSlistnoneas STATUSTICK_ALLOWHosts that may receive STATUSTICK_SECRET_<NAME>. See "Database checks".

Lower-case https_proxy, http_proxy and no_proxy work too and win over the upper-case names.

Owners and admins can change four settings on the agent's page; the agent picks them up within about 30 seconds. A variable set on the machine wins, and the dashboard shows the setting as locked.

Dashboard settingValuesVariable
Browser runsOff or 1 to 8 (default 1)BROWSER_CONCURRENCY
Max checks1 to 50 (default 5)STATUSTICK_CONCURRENCY
PausedConnected but takes no checks
Share healthSends metrics to StatusTickSTATUSTICK_SHARE_METRICS

Token

On the agent's page: Rotate (the old token works for 60 more minutes), End now (stop the old token early), Revoke (stops a leaked token at once). With many agents, rotate one at a time and choose End now after the agent's page shows the new token in use.

Target rules

The agent may reach private addresses; that is its job. Cloud metadata (169.254.169.254, fd00:ec2::254) is refused unless listed in STATUSTICK_ALLOW. With STATUSTICK_ALLOW set, only listed targets are checked. The list lives on your machine, so nobody in StatusTick can change it.

Browser checks

  • Each run is its own process, browser and work folder, stopped after 2 minutes.
  • Allow up to 2 GB of memory per concurrent run plus 256 MB for the agent.
  • The browser and the script follow the target rules; other requests fail with target not allowed by agent policy.
  • Each run is its own user, so a script can't read the agent's token, secrets or files. The agent logs at start whether runs are isolated; STATUSTICK_BROWSER_ISOLATION=user makes it refuse to start when they can't be.
  • The screenshot and trace are uploaded to StatusTick.
  • Turn browser checks off with Browser runs Off or BROWSER_CONCURRENCY=0.

Database checks

PostgreSQL, MySQL/MariaDB, Redis and MongoDB: connect, log in, run one read-only command (SELECT 1, PING, ping) or, for PostgreSQL and MySQL, your query in a read-only transaction that is rolled back. Only the one value compared with your expected value leaves the network.

Keep passwords on the agent in STATUSTICK_SECRET_* variables, name them in the monitor (passwordEnv), and bind each to its hosts:

-e STATUSTICK_SECRET_PG_PASSWORD="…" \
-e STATUSTICK_SECRET_PG_PASSWORD_HOSTS="db1.corp.example,10.0.0.5" \
-e STATUSTICK_REQUIRE_SECRET_HOSTS=true

A check that would send the secret elsewhere fails with SECRET_NOT_ALLOWED before connecting. Use a database user with minimal rights:

-- PostgreSQL
CREATE ROLE statustick_monitor LOGIN PASSWORD '…';
GRANT CONNECT ON DATABASE app TO statustick_monitor;

-- MySQL and MariaDB
CREATE USER 'statustick'@'%' IDENTIFIED BY '…';
GRANT USAGE ON *.* TO 'statustick'@'%';
# Redis 6 or later
ACL SETUSER statustick on >… -@all +ping

Grant SELECT on the tables a custom query reads.

Behind a proxy or with your own CA

-e HTTPS_PROXY="http://user:password@proxy.corp.example:3128" \
-e NO_PROXY=".corp.example,10.0.0.0/8" \
-e NODE_EXTRA_CA_CERTS=/certs/ca.pem \
-v /etc/company/ca.pem:/certs/ca.pem:ro

The connection to StatusTick and HTTP checks use the proxy unless NO_PROXY matches; other checks connect directly. The agent still resolves targets itself, so it needs DNS. A proxy refusal is logged with its status (407: wrong credentials). The agent doesn't start if NODE_EXTRA_CA_CERTS can't be read.

Offline buffer

After about 25 seconds without StatusTick, the agent keeps repeating each monitor's last check for up to an hour (not browser checks) and uploads the results later; StatusTick shows them as reported late and drops those older than 2 hours. Results live in memory unless STATUSTICK_BUFFER_DIR points at a volume user 10001 can write. Keep that folder private; database passwords and MCP auth headers are never written to it.

Heartbeat relay

Servers without internet access can ping the agent instead of the public ping URL:

-e STATUSTICK_RELAY_PORT=8080 -p 10.0.0.5:8080:8080
curl -fsS -m 10 http://10.0.0.5:8080/ping/<token>          # success
curl -fsS -m 10 http://10.0.0.5:8080/ping/<token>/start    # the job started
curl -fsS -m 10 http://10.0.0.5:8080/ping/<token>/fail     # the job failed

?run=<id> (1 to 64 letters, digits, -, _) pairs a start with its finish. Unknown tokens get 404; the relay answers 503 until it has the monitor list and 429 above 600 pings a minute per address. Pings are kept while StatusTick is unreachable. The token in the path is the only secret: publish the port on an internal address only.

Kubernetes service discovery

With STATUSTICK_DISCOVERY=kubernetes, annotated Services become monitors:

metadata:
  annotations:
    statustick.com/monitor: "http:/healthz"   # or "http:8081/ready", "http", "tcp:5432", "tcp"
    statustick.com/name: "Shop API"           # optional
    statustick.com/interval: "5m"             # optional, 30 seconds to 1 day, default 60 seconds

The target is the Service's cluster DNS name. Removing the annotation pauses the monitor; in StatusTick only its alert settings can change. Up to 100 per location. The service account needs get, list and watch on services. With STATUSTICK_ALLOW, add *.svc. Use one cluster per location.

Metrics

Labels come from fixed sets; never a target, host, monitor or token.

MetricTypeLabelsMeaning
st_build_infogaugeversion, browserAlways 1; the agent version and whether it runs browser checks (BROWSER_CONCURRENCY above 0).
st_connectedgauge1 while connected to StatusTick, 0 otherwise.
st_last_contact_timestamp_secondsgaugeUnix time of the last call StatusTick answered.
st_reconnects_totalcounterConnects after the first one.
st_jobsgaugeChecks running now.
st_checks_totalcountertype, resultChecks run, by check type (http, tcp, ping, dns, mcp, grpc, smtp, imap, ssl, postgres, mysql, redis, mongodb, browser) and result (up, down, blocked or error).
st_check_duration_secondshistogramtypeCheck response time, by check type; buckets 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30 s.
st_buffer_resultsgaugeResults kept while StatusTick is unreachable.
st_buffer_dropped_totalcounterResults dropped because the buffer was full.
st_uploads_totalcounterresultResult uploads to StatusTick, by result: ok, failed (retried) or rejected.
st_browser_runs_activegaugeBrowser checks on only: browser checks running now.
st_browser_concurrencygaugeBrowser checks on only: browser checks that may run at once (the "Browser runs" setting, or BROWSER_CONCURRENCY).
st_relay_pings_totalcounterresultHeartbeat relay on: relayed pings, by result: accepted, rejected or failed.

Plus process_* CPU and resident memory. Scrape with METRICS_PORT on an internal address. Example alert:

- alert: StatusTickAgentDisconnected
  expr: st_connected == 0
  for: 5m

Share health (off by default) sends these metrics to StatusTick every minute; it keeps only the latest snapshot. STATUSTICK_SHARE_METRICS=false turns sharing off for good.

Troubleshooting

docker exec statustick-agent statustick-agent doctor

doctor checks the token format, DNS, TCP and TLS to StatusTick, the proxy, the token and the clock, printing OK, FAIL with a fix, or SKIP, and exits 1 on a failure. --target <url> also tests one target; --report hides host names and addresses for support. The agent logs one line per state change (Connected, Disconnected, Token rejected, Update required).

Updates

ghcr.io/statustick/agent:1 follows every 1.x release; pin 1.0.1 to stay on one.

docker compose pull statustick-agent && docker compose up -d statustick-agent

Agents below StatusTick's recommended version show "Update available"; below the minimum they are refused. A new minimum is announced by email at least 30 days ahead, except for security fixes.

All docs