# Self-host Edges

Deployment prerequisites, verification, and recovery for Edges.

Source: https://railgrid.ai/docs/self-hosting/providers/edges/


## Prerequisites

You need a Kubernetes runtime you administer, Helm, network access from the provider runtime to the hub and advertised virtual-workspace endpoints, and permission to onboard this provider. Use the [common provider flow](https://railgrid.ai/docs/self-hosting/providers/) to obtain the workspace kubeconfig. The examples below use a Secret named `railgrid-provider-kubeconfig` with data key `kubeconfig`.

Edge agents dial the hub's **public** URL and hold a reverse tunnel open through it. Your [ingress](https://railgrid.ai/docs/self-hosting/hub/ingress/) must allow long-lived connections to the hub: on a cloud load balancer, a backend timeout of an hour rather than the default 30 seconds.

## Install

```bash
kubectl create namespace railgrid-provider-edges
kubectl --namespace railgrid-provider-edges create secret generic railgrid-provider-kubeconfig \
  --from-file=kubeconfig=./edges.kubeconfig
```

`edges-values.yaml`:

```yaml
replicaCount: 2
hub:
  url: https://railgrid-hub.railgrid-system.svc.cluster.local:9443
  # What agents dial; baked into the agent kubeconfigs the provider mints.
  externalURL: https://console.example.com
  # What the provider itself uses for hub calls in a split-horizon setup.
  internalURL: https://railgrid-hub.railgrid-system.svc.cluster.local:9443
  tokenSecretRef:
    name: ""
catalogEntry:
  enabled: true
```

```bash
helm upgrade --install edges oci://ghcr.io/railgrid/charts/railgrid-edges-provider \
  --version CHART_VERSION --namespace railgrid-provider-edges --values edges-values.yaml
```

The chart README contains the matching values table for the deployed version: [chart instructions](https://github.com/railgrid/railgrid/blob/main/providers/edges/deploy/chart/README.md).

## Provider requirements

**Hub URLs.** `hub.externalURL` is what agents dial from outside and defaults to `hub.url` when empty, which is wrong for an in-cluster `hub.url`. If the hub's public certificate is not publicly trusted, give agents its CA with `hub.caData` or `hub.caSecretRef`; agents verify the hub serving certificate from the kubeconfig the provider mints.

**Scaling.** The provider is safe to scale. Each agent dials one replica; that replica claims the tunnel in a Lease registry in the provider workspace, and the other replicas relay pickups and data-plane requests to the owner over `internalPort` (pod to pod, never on the Service). Preserve `internalPort` and the provider workspace credential when changing replica counts.

**SSH host keys.** Edges with a known host key are always verified. Prefer pinning `spec.sshHostKey` or `sshHostKeyPolicy=tofu` on the edge over the legacy `allowUnverifiedSSHHostKey` escape hatch.

## Verify

Run `kubectl -n railgrid-provider-edges get pods` and wait for Ready and a fresh heartbeat. A fresh provider stays unready until a workspace enables it; see [the common flow](https://railgrid.ai/docs/self-hosting/providers/#a-fresh-provider-is-unready-until-a-workspace-binds-it). Enable Edges in a test workspace, connect one disposable agent, and verify reconnect plus kubectl/SSH after a pod restart using the [Edges quickstart](https://railgrid.ai/docs/use/edges/quickstart/). An agent that connects and then drops every 30 seconds points at the load-balancer timeout.

## Recover

For a failed upgrade, preserve agent join state and inspect Lease/relay logs before deleting pods. Roll back the chart/image, verify the internal listener is reachable between replicas, and reconnect one test agent before restoring normal traffic.

## Configuration reference

[Chart values](https://github.com/railgrid/railgrid/blob/main/providers/edges/deploy/chart/values.yaml) are authoritative for this source baseline. Keep the deployed image and chart versions recorded together.
