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
| Free | Starter | Pro | Business | |
|---|---|---|---|---|
| Self-hosted runners | — | 1 | 3 | 10 |
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:
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| Variant | Image suffix | Supports |
|---|---|---|
| Standard | -standard | All 7 standard check types. No browsers. The default choice. |
| Chromium | -chromium | Standard checks + Chromium browser checks. |
| Firefox | -firefox | Standard checks + Firefox browser checks. |
| WebKit | -webkit | Standard checks + WebKit browser checks. |
| Full | -full | Standard 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
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=10001Environment variable reference
| Variable | Type | Default | Description |
|---|---|---|---|
PATHWATCH_API_URL | string | — (required) | API endpoint, normally https://api.pathwatch.app. Must be HTTPS — the runner refuses plain-HTTP URLs. |
PATHWATCH_TOKEN | string | — (required) | The runner token from registration. Must start with rt_. |
RUNNER_NAME | string | pathwatch-runner | Display name shown in the dashboard. |
RUNNER_REGION | string | unknown | Free-form location label shown alongside results from this runner. |
RUNNER_MODE | enum | persistent | Leave at persistent for self-hosted runners (the other modes are for PathWatch-managed cloud infrastructure). |
POLL_INTERVAL_MS | integer | 5000 | How often the runner polls for new jobs. Minimum 1000. |
HEARTBEAT_INTERVAL_MS | integer | 30000 | How often the runner reports liveness. Minimum 5000. A runner that misses heartbeats shows as offline in the dashboard. |
CONCURRENCY | integer | 10 | Maximum checks executed in parallel. 1–100. |
BROWSERS | enum | none | Which browser engines this runner offers: none, chromium, firefox, webkit, or all. Must match an image variant that ships the engine. |
BROWSER_POOL_SIZE | integer | 2 | Warm browser instances kept ready for browser checks. 1–20. Raise for high browser-check volume; each instance costs memory. |
ALLOW_PRIVATE_IPS | bool | false | Allow checks against private/internal addresses (RFC 1918, localhost, link-local). Required for monitoring internal targets; leave off otherwise. |
LOG_LEVEL | enum | info | One of fatal, error, warn, info, debug, trace, silent. |
LOG_FORMAT | enum | json | json for log shippers, pretty for humans reading docker logs. |
ALLOW_UNENCRYPTED_SESSION | bool | false | Opt 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.
Related pages
- IPv6 monitoring — runners are the only way to run IPv6 checks.
- Browser Lite and Browser Flow — self-hosted browser slots.
- Limits & quotas — runner counts per plan.
- Add-ons — extra runner and browser slots.