Skip to content

Self-hosted runners

A self-hosted runner is a Docker container you run on your own infrastructure. It polls PathWatch for check jobs, executes them from your network, and reports results back over an encrypted session. PathWatch stores and alerts on the results exactly as it does for cloud regions.

Use a self-hosted runner when you need to:

  • Monitor private endpoints — internal admin panels, staging environments, services behind a VPN or on RFC 1918 addresses.
  • Check from your own vantage point — your office, your data centre, a region PathWatch cloud doesn’t cover.
  • Run IPv6 checks — cloud regions are IPv4-only; self-hosted runners use the host’s network stack, so dual-stack hosts get IPv6 automatically. See IPv6 monitoring.
  • Run browser checks on your own hardware — self-hosted browser slots have a 1-minute minimum interval and no managed runtime cap.

Plan availability

FreeStarterProBusiness
Self-hosted runners1310

Extra runners are available as an add-on (+1 runner, $4.99/mo, Starter and above). See Limits & quotas and Add-ons.

What runs on a runner

All seven standard check types run on any runner variant: HTTP, keyword, SSL certificate, TCP port, DNS, ping and domain expiration. Browser checks (Lite and Flow) additionally require a browser-capable image variant (below) and a self-hosted browser monitor slot.

Heartbeat monitors are inbound and never run on runners.

Registration

A runner authenticates with a runner token (rt_…). The token is shown once at creation and stored hashed — copy it immediately.

From the dashboard: open Runners, click Add runner, give it a name (and optionally a location label), and copy the token from the confirmation screen.

From the API:

Terminal window
curl -X POST https://api.pathwatch.app/api/v1/runners \
-H "Authorization: Bearer pw_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "office-runner-1"}'

The response includes the one-time token. API keys need the runners:write scope. If you lose a token, revoke the runner and register a new one — tokens cannot be retrieved later.

Revoking a runner (dashboard, or DELETE /api/v1/runners/:id) immediately invalidates its token; the container stops receiving jobs.

Image variants

Images are published to GitHub Container Registry as multi-arch (amd64 + arm64) tags:

ghcr.io/vertexionplatforms/pathwatch-runner-<variant>:latest
VariantImage suffixSupports
Standard-standardAll 7 standard check types. No browsers. The default choice.
Chromium-chromiumStandard checks + Chromium browser checks.
Firefox-firefoxStandard checks + Firefox browser checks.
WebKit-webkitStandard checks + WebKit browser checks.
Full-fullStandard checks + all three browser engines. Largest image.

Pick the smallest variant that covers the browsers you need — browser images are an order of magnitude larger than standard.

Quick start — docker run

Terminal window
docker run -d \
--name pathwatch-runner \
--restart unless-stopped \
--read-only \
--tmpfs /tmp:size=256M \
--cap-add NET_RAW \
-e PATHWATCH_API_URL=https://api.pathwatch.app \
-e PATHWATCH_TOKEN=rt_your_token_here \
-e RUNNER_NAME=office-runner-1 \
-e RUNNER_REGION=office-london \
ghcr.io/vertexionplatforms/pathwatch-runner-standard:latest

--cap-add NET_RAW is required for ICMP ping checks; omit it if you don’t run ping monitors. --read-only plus a tmpfs for /tmp matches how the image is designed to run — nothing is written to disk.

Docker Compose

services:
runner:
image: ghcr.io/vertexionplatforms/pathwatch-runner-standard:latest
restart: unless-stopped
read_only: true
tmpfs:
- /tmp:size=256M
cap_add:
- NET_RAW # ICMP ping checks
environment:
PATHWATCH_API_URL: https://api.pathwatch.app
PATHWATCH_TOKEN: ${RUNNER_TOKEN}
RUNNER_NAME: office-runner-1
RUNNER_REGION: office-london
# Browser-capable runner (optional)
runner-chromium:
image: ghcr.io/vertexionplatforms/pathwatch-runner-chromium:latest
restart: unless-stopped
read_only: true
shm_size: 512m # Chromium shared memory
tmpfs:
- /tmp:size=512M # Browser profiles live in RAM
cap_add:
- NET_RAW
environment:
PATHWATCH_API_URL: https://api.pathwatch.app
PATHWATCH_TOKEN: ${RUNNER_CHROMIUM_TOKEN}
RUNNER_NAME: office-runner-chromium
BROWSERS: chromium
BROWSER_POOL_SIZE: "2"

Each runner needs its own token — register one runner per container. Firefox and WebKit variants additionally need cap_add: [SYS_ADMIN] (browser sandboxing uses user namespaces) and a writable home tmpfs:

cap_add:
- NET_RAW
- SYS_ADMIN
tmpfs:
- /tmp:size=512M
- /home/pathwatch:size=64M,uid=10001,gid=10001

Environment variable reference

VariableTypeDefaultDescription
PATHWATCH_API_URLstring— (required)API endpoint, normally https://api.pathwatch.app. Must be HTTPS — the runner refuses plain-HTTP URLs.
PATHWATCH_TOKENstring— (required)The runner token from registration. Must start with rt_.
RUNNER_NAMEstringpathwatch-runnerDisplay name shown in the dashboard.
RUNNER_REGIONstringunknownFree-form location label shown alongside results from this runner.
RUNNER_MODEenumpersistentLeave at persistent for self-hosted runners (the other modes are for PathWatch-managed cloud infrastructure).
POLL_INTERVAL_MSinteger5000How often the runner polls for new jobs. Minimum 1000.
HEARTBEAT_INTERVAL_MSinteger30000How often the runner reports liveness. Minimum 5000. A runner that misses heartbeats shows as offline in the dashboard.
CONCURRENCYinteger10Maximum checks executed in parallel. 1–100.
BROWSERSenumnoneWhich browser engines this runner offers: none, chromium, firefox, webkit, or all. Must match an image variant that ships the engine.
BROWSER_POOL_SIZEinteger2Warm browser instances kept ready for browser checks. 1–20. Raise for high browser-check volume; each instance costs memory.
ALLOW_PRIVATE_IPSboolfalseAllow checks against private/internal addresses (RFC 1918, localhost, link-local). Required for monitoring internal targets; leave off otherwise.
LOG_LEVELenuminfoOne of fatal, error, warn, info, debug, trace, silent.
LOG_FORMATenumjsonjson for log shippers, pretty for humans reading docker logs.
ALLOW_UNENCRYPTED_SESSIONboolfalseOpt out of mandatory payload encryption. Never set this against the production API — it exists for local development only.

Monitoring private networks

By default the runner refuses to check private, loopback and link-local addresses — this protects you from a misconfigured monitor probing infrastructure you didn’t intend it to. To monitor internal targets, set ALLOW_PRIVATE_IPS=true on the runner and assign that runner to the monitor. Cloud regions can never reach your private network; monitors for internal targets should select self-hosted runners only.

Security model

  • HTTPS only. The runner refuses to start with a plain-HTTP PATHWATCH_API_URL.
  • Encrypted session, fail closed. On startup the runner negotiates an encrypted session (AES-256-GCM) with the API for all job and result payloads. If the handshake fails, the runner refuses to start rather than fall back to unencrypted payloads.
  • Token security. Runner tokens are stored hashed on the PathWatch side and displayed exactly once. Treat the token like a password; revoke the runner if it leaks.
  • Read-only container. The image is designed to run with a read-only filesystem and tmpfs-only writable paths — no check data, secrets or artifacts persist on your host between restarts.
  • No inbound ports. The runner only makes outbound HTTPS connections to the API. You don’t need to open any firewall ports towards it.

Runner status

The dashboard shows each runner as online or offline based on its heartbeats, along with last-seen and last-check timestamps. The same data is available via GET /api/v1/runners and GET /api/v1/runners/:id/status. If a runner goes offline mid-check, the jobs it had claimed are detected as stale and automatically re-queued.