> ## Documentation Index
> Fetch the complete documentation index at: https://docs.use.observer/llms.txt
> Use this file to discover all available pages before exploring further.

# Install on Kubernetes

> Deployment manifest with Secret-bound credentials.

The recommended deployment path for production. Single-replica
Deployment, agent key delivered through a Kubernetes Secret.

## Prerequisites

* A Kubernetes cluster you can deploy into.
* An agent key from the Observer console.
* For Prometheus probes, a reachable Prometheus URL inside the
  cluster (typically a `Service` in the monitoring namespace).
  `PROMETHEUS_SERVER_URL` is optional; drop it from the manifest
  when the agent runs only active probes.

> [!NOTE]
>
> **Proxies, private CAs and restricted egress**
>
> If the host reaches the internet through a proxy, a
> TLS-intercepting proxy or a private CA, or cannot pull from public
> registries, see
> [Run behind a proxy or in a restricted network](https://docs.use.observer/agent/guides/restricted-networks.md).

## Steps

**1. Create a namespace and Secret**

```bash theme={null}
kubectl create namespace observer
kubectl create secret generic observer-agent \
  --namespace observer \
  --from-literal=agent-key='obs_live_...'
```

**2. Apply the Deployment**

```yaml title="agent.yaml" theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: observer-agent
  namespace: observer
spec:
  replicas: 1
  selector:
    matchLabels: { app: observer-agent }
  template:
    metadata:
      labels: { app: observer-agent }
    spec:
      containers:
        - name: agent
          image: ghcr.io/useobserver/agent:1.7.3
          imagePullPolicy: IfNotPresent
          ports:
            - { name: dashboard, containerPort: 10101 }
          env:
            - name: AGENT_KEY
              valueFrom:
                secretKeyRef: { name: observer-agent, key: agent-key }
            - name: CLOUD_SERVER_URL
              value: https://use.observer
            - name: PROMETHEUS_SERVER_URL
              value: http://prometheus.monitoring.svc.cluster.local:9090
          volumeMounts:
            - { name: data, mountPath: /data }
          resources:
            requests: { cpu: "50m", memory: "64Mi" }
            limits:   { cpu: "500m", memory: "256Mi" }
      volumes:
        - name: data
          emptyDir: {}
```

The `/data` volume holds the [local queue](https://docs.use.observer/agent/concepts/local-queue.md).
An `emptyDir` survives container restarts but not pod rescheduling.
To keep queued readings when the pod is replaced, mount a
PersistentVolumeClaim on `/data` instead.

```bash theme={null}
kubectl apply -f agent.yaml
```

**3. Confirm the connection**

Port-forward the dashboard:

```bash theme={null}
kubectl -n observer port-forward deploy/observer-agent 10101:10101
```

Open `http://localhost:10101`. The *Cloud link* card shows the
last heartbeat within 30 seconds. The console's Agents page
marks the agent as **running** within 90 seconds.

> [!WARNING]
>
> **Replica count**
>
> Run a single replica per agent identity. The agent's local queue
> uses an embedded SQLite file inside the container; running two
> pods with the same key splits the queue and confuses the cloud's
> agent.offline detection.

> [!NOTE]
>
> **Pinning**
>
> Pin to an exact version (`agent:1.7.3`), or to the major tag
> (`agent:1`) to pick up 1.x releases as they ship. `latest` moves
> only when a release is tagged. Track new releases at
> [github.com/useobserver/agent/releases](https://github.com/useobserver/agent/releases)
> and roll forward when ready.

## Optional: dashboard Service

To expose the dashboard inside the cluster (without
`port-forward`), add a ClusterIP Service. Do not expose the
dashboard externally; the dashboard is operator-facing only.

The dashboard binds `127.0.0.1` unless both `DEBUG_DASHBOARD_HOST`
and `DEBUG_DASHBOARD_TOKEN` are set, so a Service cannot reach it by
default. Add a token to the Secret:

```bash theme={null}
kubectl -n observer patch secret observer-agent --type merge \
  -p "{\"stringData\":{\"dashboard-token\":\"$(openssl rand -hex 32)\"}}"
```

Then add both variables to the container's `env` in `agent.yaml`
and apply it again:

```yaml theme={null}
            - name: DEBUG_DASHBOARD_HOST
              value: 0.0.0.0
            - name: DEBUG_DASHBOARD_TOKEN
              valueFrom:
                secretKeyRef: { name: observer-agent, key: dashboard-token }
```

```yaml title="agent-service.yaml" theme={null}
apiVersion: v1
kind: Service
metadata:
  name: observer-agent
  namespace: observer
spec:
  type: ClusterIP
  selector: { app: observer-agent }
  ports:
    - { name: dashboard, port: 10101, targetPort: 10101 }
```

Requests through the Service, except `/healthz`, must send
`Authorization: Bearer <token>`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.