---
title: 'Private Locations'
description: 'Deploy Yorker runners on your own infrastructure to monitor internal services, staging environments, and VPNs.'
section: 'Guides'
canonical_url: 'https://yorkermonitoring.com/docs/guides/private-locations'
---

# Private Locations

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; the only difference is where the agent executes.

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`):

```bash
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:

```bash
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 repository includes a reference Docker Compose configuration at `docker/docker-compose.private-agent.yml` and an environment template at `docker/private-agent.env.example`. The template pre-fills `RUNNER_MODE`, `CONTROL_PLANE_URL`, and `LOCATION_TYPE` with their required values. You only need to supply the four values specific to your deployment:

```bash
# Copy the reference environment file
cp docker/private-agent.env.example docker/.env
```

Open `docker/.env` and fill in:

```bash
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 telemetry
```

Then start the agent:

```bash
docker compose -f docker/docker-compose.private-agent.yml up -d
```

### Choosing an image

Two runner Dockerfiles are available:

| Dockerfile | Includes | Use when |
|---|---|---|
| `Dockerfile.runner-heavy` (~1 GB) | Playwright + Chromium | You need browser checks |
| `Dockerfile.runner-light` (~200 MB) | HTTP/API checks only | You only run HTTP/ping monitors |

The default Compose file builds the heavy image. To switch to the lighter image, comment out the `yorker-agent` service in the Compose file and uncomment `yorker-agent-light`.

---

## 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 list` and 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](#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:

```yaml
monitors:
  - name: Internal API
    type: http
    url: https://api.internal.example.com/health
    locations:
      - loc_us_east          # hosted location
      - loc_abcdef123456     # your private location
```

Deploy the config to apply:

```bash
yorker deploy
```

---

## 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 |
| 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) |
| Image build fails | Missing Docker or build context | Run `docker build` from the repository root with `-f docker/Dockerfile.runner-heavy` |
| Browser checks fail | Using the light image | Switch to `runner-heavy`, which includes Playwright and Chromium |
