Navigation
Getting Started
Guides
Integrations
Guides
Private Locations
Deploy Yorker runners on your own infrastructure to monitor internal services, staging environments, and VPNs.
A private location runs the Yorker check runner on your own infrastructure instead of Yorker's hosted fleet. Use it to monitor internal services, staging environments, or anything behind a VPN -- from inside your own network. The same monitors, alerting, and dashboards work identically, with one exception: scripted browser monitors run on hosted locations only.
Private location runs are billed at 50% of hosted runs because you provide the compute.
Prerequisites
- A Yorker plan that includes private locations (free tier: 0; paid: up to 2; enterprise: unlimited)
- Docker installed on the target machine
- Outbound HTTPS access from the agent machine to
yorkermonitoring.com:443-- no inbound connections are required
Step 1: Create a Location
To create a location via the CLI, provide a unique slug (--name) and a human-readable label (--display-name):
yorker locations create --name hq-data-center --display-name "HQ Data Center"The CLI also auto-generates a runner key. Use the key and location ID from the output when continuing with Step 3 below.
To create a location via the dashboard: go to Settings > Locations and click Add Location.
Both paths return a location ID in the form loc_.... Save it -- you will need it in the next step.
Step 2: Generate a Runner Key
Runner keys authenticate the agent to the control plane. Each key is shown only once.
To generate a key via the CLI:
yorker locations keys create <location-id>To generate a key via the dashboard: expand the location row, enter a key name, and click Create Key.
Copy the key immediately -- it cannot be retrieved after the page is closed.
Step 3: Deploy the Agent
The agent is published as a Docker image. Download the Compose file and the environment template into an empty directory on the machine that will run it:
curl -fsSLO https://yorkermonitoring.com/agent/docker-compose.yml
curl -fsSL -o .env https://yorkermonitoring.com/agent/agent.env.exampleThe template pre-fills RUNNER_MODE, CONTROL_PLANE_URL, and LOCATION_TYPE with their required values. Open .env and fill in the four values specific to your deployment:
RUNNER_API_KEY=rk_... # The runner key from Step 2
LOCATION_ID=loc_... # The location ID from Step 1
TEAM_ID=team_... # Included in the `yorker locations create` CLI output
LOCATION_NAME=HQ Data Center # Human-readable label for logs and telemetryThe runner key is a credential. Keeping it in .env keeps it out of your shell history and the process list, which a one-line docker run -e RUNNER_API_KEY=... does not. Restrict the file to your own user with chmod 600 .env.
The dashboard and the CLI also print a docker run command when you create a runner key, for trying an agent quickly without Compose. It comes in two steps: the first reads the key into your shell without showing it, and the second starts the agent, so the key is not written into the command. The image in that command is the current release, named by version and by digest (yorker-agent:1.0.2@sha256:...) instead of latest, so Docker only runs the exact image that was released.
Then start the agent:
docker compose up -dChoosing an image
Two images are published, for linux/amd64 and linux/arm64:
| Image | Runs | Size |
|---|---|---|
ghcr.io/reverse-sweep-ltd/yorker-agent | HTTP, MCP, and browser monitors (includes Playwright + Chromium) | ~550 MB download, ~2 GB on disk |
ghcr.io/reverse-sweep-ltd/yorker-agent-light | HTTP and MCP monitors only | ~130 MB download, ~570 MB on disk |
Both images run as an unprivileged user, and the Compose file drops all Linux capabilities and sets no-new-privileges. The agent needs no inbound ports, no volumes, and no elevated permissions.
The Compose file runs yorker-agent by default. To run the lighter image, add this line to .env and run docker compose up -d again:
YORKER_AGENT_IMAGE=yorker-agent-lightScreenshots
Browser monitors on a private location capture the same screenshots as hosted ones. The agent sends each screenshot to Yorker over the outbound HTTPS connection it already uses for results, and they appear in the monitor's filmstrip. There is nothing to configure, and no extra host to allow through a firewall. Each screenshot can be up to 4 MB, and a location can send up to 12,000 an hour, which is far more than its monitors produce in normal use.
This needs agent 1.0.2 or later. An older agent runs browser monitors but its screenshots never reach Yorker; update it.
Screenshots are images of the pages the agent loads, so with the default setup those images leave your network and are stored by Yorker, with the same retention as hosted screenshots. If they must stay in storage you control, give the agent an S3-compatible bucket in .env:
ARTIFACT_S3_ENDPOINT=https://s3.eu-west-2.amazonaws.com
ARTIFACT_S3_BUCKET=synthetics-artifacts
ARTIFACT_S3_ACCESS_KEY_ID=...
ARTIFACT_S3_SECRET_ACCESS_KEY=...
ARTIFACT_S3_REGION=eu-west-2 # "auto" for Cloudflare R2 and MinIO
ARTIFACT_PUBLIC_URL= # optional: base URL put in front of each object key in telemetryThe agent then uploads screenshots to that bucket instead of sending them to Yorker. Yorker cannot read your bucket, so the filmstrip in the dashboard stays empty for that location. The screenshot links are included in the OTLP telemetry the agent emits, so you can open them from your own backend.
Direct OTLP export
The agent can export metrics, traces, and logs straight to your own OTel-compatible backend, entirely from inside your network (this connection never transits Yorker). Set these in .env:
OTLP_ENDPOINT=https://api.honeycomb.io
OTLP_API_KEY= # sent verbatim as "Authorization" (leave unset if not needed)
OTEL_EXPORTER_OTLP_HEADERS=x-honeycomb-team=your-team-key,x-honeycomb-dataset=yorkerOTEL_EXPORTER_OTLP_HEADERS follows the standard OTel env var format: comma-separated key=value pairs, values URL-encoded. Use it for backends that need a header other than Authorization (Honeycomb, Datadog's dd-api-key, New Relic's api-key, SigNoz Cloud's signoz-ingestion-key) or more than one header. If a header name here collides with OTLP_API_KEY's Authorization, the entry in OTEL_EXPORTER_OTLP_HEADERS wins.
Step 4: Verify Health
After the agent starts, it begins polling the control plane. To verify it is connected:
- Dashboard: the location's status badge turns green (Active) in Settings > Locations.
- CLI: run
yorker locations listand check the status column.
Health states are derived from the time since the last successful poll:
| Status | Meaning |
|---|---|
| Active | Last poll within the past 5 minutes |
| Degraded | Last poll 5--10 minutes ago |
| Offline | Last poll more than 10 minutes ago, or never connected |
If the agent does not appear Active within a few minutes, see Troubleshooting below.
Step 5: Assign the Location to a Monitor
Monitors only execute in the locations they are assigned to. A monitor can be assigned to any mix of hosted and private locations.
To assign via the dashboard: edit a monitor and open the location picker. Your private location appears under the Private group with its current health badge.
To assign via yorker.config.yaml, add the location ID to the monitor's locations array:
monitors:
- name: Internal API
type: http
url: https://api.internal.example.com/health
locations:
- loc_us_east # hosted location
- loc_abcdef123456 # your private locationDeploy the config to apply:
yorker deployUpdating the Agent
Hosted locations pick up runner changes automatically. A private agent runs on your infrastructure, so it stays on the image it was started with until you update it. An agent that falls behind keeps running the monitors it understands, but it cannot run monitor types or settings that were added after its release.
To move to the newest release:
docker compose pull
docker compose up -dThe agent restarts in a few seconds and resumes polling. Monitors assigned to hosted locations are unaffected while it restarts.
If you started the agent with the docker run command from the dashboard or the CLI instead of Compose, that command names a specific release, so running it again starts the same version. To upgrade:
-
Create a new runner key for the location, in the dashboard or with
yorker locations keys create <location-id>. It comes with the start command for the current release. -
Remove the old container:
docker rm -f yorker-agent-loc_abcdef123456 # your location ID -
Run the two commands shown with the new key.
-
Revoke the old key.
If you pinned a release with YORKER_AGENT_VERSION, change the pin first; docker compose pull on its own fetches the pinned version again.
Choosing how updates arrive
By default the Compose file tracks the latest tag, so every docker compose pull fetches the newest release. Two common setups:
-
Follow releases automatically. Keep
latestand run the two commands above on a schedule, for example a weekly cron job. -
Control each upgrade. Pin a release in
.envand change the line when you are ready to upgrade:YORKER_AGENT_VERSION=1.0.1
Released version tags are never overwritten, so a pinned agent runs the same image until you change the pin.
Checking what is running
The agent reports its version to Yorker each time it polls. Settings > Locations and yorker locations list show it in the Agent column, flagged Update available when a newer release exists. An agent started from a build that predates published releases shows Unknown version; update it the same way.
The agent also serves its version, build, and what it can run on the health port:
docker compose exec yorker-agent curl -s http://localhost:8080/versionMonitors an agent cannot run
Some monitors cannot run on a given agent. When one is assigned to a private location, the location is flagged in Settings > Locations (expand the row for the list) and in yorker locations list, with the reason:
| Monitor | Runs on |
|---|---|
| HTTP, MCP | yorker-agent and yorker-agent-light |
| Browser (URL mode) | yorker-agent only |
| Browser (scripted) | Hosted locations only |
A monitor that cannot run on a private location still runs on its other locations.
Network Requirements
The agent only needs outbound connectivity -- no inbound connections are required and no firewall rules need to be opened toward Yorker.
| Requirement | Detail |
|---|---|
| Outbound HTTPS | yorkermonitoring.com:443 -- for polling checks and submitting results and screenshots |
| Outbound HTTPS (install and update only) | ghcr.io:443 and pkg-containers.githubusercontent.com:443 -- for pulling the agent image |
| Internal network access | The agent must be able to reach the services it monitors (e.g., internal hostnames, VPN resources) |
There is no VPN tunnel from the agent to Yorker's infrastructure. All communication is initiated by the agent over standard HTTPS.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Location stays Offline | Wrong runner key or location ID | Verify RUNNER_API_KEY and LOCATION_ID in .env match what was generated in Steps 1 and 2 |
| Location stays Offline | Firewall blocking outbound HTTPS | Allow outbound connections from the agent machine to yorkermonitoring.com:443 |
| Location is Active but no checks run | Wrong TEAM_ID | The runner polls with team scoping -- verify TEAM_ID matches your team in Settings |
| Checks not executing | Agent is connected but no checks assigned | Assign the private location to at least one monitor (Step 5) |
docker compose pull fails | Registry blocked by an egress firewall | Allow outbound HTTPS to ghcr.io and pkg-containers.githubusercontent.com |
| Browser checks fail | Using the light image | Remove YORKER_AGENT_IMAGE=yorker-agent-light from .env to run yorker-agent, which includes Playwright and Chromium |
| Browser monitors run but show no screenshots | Agent is older than 1.0.2 | Update the agent |
| Browser monitors run but show no screenshots | ARTIFACT_S3_* is set, so screenshots go to your own bucket | Expected. Remove the ARTIFACT_S3_* lines from .env to have them sent to Yorker and shown in the filmstrip; see Screenshots |
| A new monitor type or setting does not work | Agent is older than the feature | Update the agent |