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

# Controller Configuration

> Configuration options for the OpenLIT Controller

The Controller is configured via a YAML file mounted at `/etc/openlit/config.yaml` or through environment variables.

## Configuration File

```yaml /etc/openlit/config.yaml theme={null}
openlit_url: "http://openlit:3000"
otlp_endpoint: "http://openlit:4318"
poll_interval: 60s
environment: "production"
api_listen: ":4321"
```

## Configuration Reference

| Field           | Env Variable                  | Default                 | Description                                                                                                                                                                                                                                                         |
| --------------- | ----------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `openlit_url`   | `OPENLIT_URL`                 | (required)              | URL of the OpenLIT dashboard for the poll API                                                                                                                                                                                                                       |
| `otlp_endpoint` | `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4318` | OTLP HTTP endpoint for sending traces and metrics                                                                                                                                                                                                                   |
| `poll_interval` | `OPENLIT_POLL_INTERVAL`       | `60s`                   | Duration between poll cycles (e.g., `60s`, `2m`)                                                                                                                                                                                                                    |
| `environment`   | `OPENLIT_ENVIRONMENT`         | `default`               | Deployment environment label (e.g., `production`, `staging`)                                                                                                                                                                                                        |
| `api_listen`    | `OPENLIT_API_LISTEN`          | `:4321`                 | Address for the Controller's REST API                                                                                                                                                                                                                               |
| `cluster_id`    | `OPENLIT_CLUSTER_ID`          | `default`               | Identifier for multi-cluster setups                                                                                                                                                                                                                                 |
| `api_key`       | `OPENLIT_API_KEY`             | —                       | API key for authenticating with the dashboard                                                                                                                                                                                                                       |
| `sdk_version`   | `OPENLIT_SDK_VERSION`         | (auto)                  | Pin a specific OpenLIT Python SDK version                                                                                                                                                                                                                           |
| —               | `OPENLIT_INSTANCE_ID`         | (auto)                  | Override the controller's identity. By default, the instance ID is derived automatically (hostname on Linux, host hostname on Docker, `NODE_NAME` on K8s). Set this to force a stable, custom identity — useful when the automatic ID is not stable across restarts |

Environment variables take precedence over config file values.

## Deployment Mode

The Controller auto-detects its deployment mode:

* **Kubernetes** — Detected when the `KUBERNETES_SERVICE_HOST` environment variable is present
* **Docker** — Detected when `/var/run/docker.sock` is accessible
* **Linux** — Default fallback when neither Kubernetes nor Docker is detected

You can override auto-detection with the `OPENLIT_DEPLOY_MODE` environment variable:

```bash theme={null}
OPENLIT_DEPLOY_MODE=docker  # Force Docker mode
OPENLIT_DEPLOY_MODE=linux   # Force Linux mode
```

## Kubernetes Configuration

### Required RBAC

The Controller needs the following ClusterRole to discover and modify workloads:

```yaml theme={null}
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch", "delete", "create"]
  - apiGroups: ["apps"]
    resources: ["deployments", "daemonsets", "statefulsets", "replicasets"]
    verbs: ["get", "list", "watch", "update", "patch"]
```

* `get/list/watch` on pods — for service discovery
* `delete/create` on pods — for naked pod Agent Observability (requires pod restart)
* `update/patch` on deployments/daemonsets/statefulsets — for Agent Observability SDK injection

### Volume Mounts

| Mount                     | Host path                       | Purpose                                                                                                                     |
| ------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `/host/proc`              | `/proc` (read-only)             | Scans `/proc/net/tcp` to discover processes with connections to LLM APIs, reads `/proc/<pid>/cgroup` for container metadata |
| `/sys/kernel/debug`       | `/sys/kernel/debug` (read-only) | Required by the kernel for attaching eBPF kprobes to `tcp_connect`                                                          |
| `/sys/fs/bpf`             | `/sys/fs/bpf` (read-write)      | eBPF map pinning — allows the OBI engine to persist eBPF maps across probe reloads                                          |
| `/etc/openlit-controller` | ConfigMap                       | Configuration file (managed by Helm chart)                                                                                  |

### Security Context

The Controller requires `privileged: true` and `hostPID: true` because eBPF kprobe attachment and `/proc` scanning across all namespaces require elevated kernel access. The Controller itself is read-only (it inspects traffic, it doesn't modify it).

## Docker Configuration

### Required Volumes

```yaml theme={null}
volumes:
  - /proc:/host/proc:ro                        # /proc/net/tcp scanning for LLM connection discovery
  - /sys/kernel/debug:/sys/kernel/debug:ro     # eBPF kprobe attachment
  - /sys/fs/bpf:/sys/fs/bpf:rw                # eBPF map pinning
  - /var/run/docker.sock:/var/run/docker.sock  # Container discovery + SDK injection
```

* **`/proc`** — Scan process network connections to detect LLM API calls
* **`/sys/kernel/debug`** + **`/sys/fs/bpf`** — Required for eBPF operation (LLM traffic interception)
* **Docker socket** — Discover running containers, read labels/metadata, and inject the Python SDK for Agent Observability

## Linux Configuration

### Systemd Integration

For Agent Observability on Linux, the Controller manages systemd drop-in files to inject the SDK. It needs:

* Write access to `/etc/systemd/system/` for creating drop-in configurations
* Ability to run `systemctl daemon-reload` and `systemctl restart`

### Proc Filesystem

The Controller reads `/proc` to discover running processes and their network connections. Ensure `/host/proc` is mounted (or the Controller runs on the host directly with access to `/proc`).

## Controller Identity

Each controller registers itself in the dashboard with a unique `instance_id`. This ID determines whether a restarted controller appears as the same entry or a new one on the Agents page.

| Platform       | Default `instance_id`          | Behavior on restart                                                                                               |
| -------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **Linux**      | Machine hostname               | Stable — hostname persists across restarts                                                                        |
| **Docker**     | Host hostname + container hash | Stable across `docker restart` / `stop+start`. New entry on `docker rm && run` (old entry auto-detected as stale) |
| **Kubernetes** | `NODE_NAME` (downward API)     | Stable — same node, same ID across pod restarts                                                                   |

To override the automatic identity on any platform, set `OPENLIT_INSTANCE_ID`:

```bash theme={null}
OPENLIT_INSTANCE_ID="my-controller-1" openlit-controller
```

The dashboard automatically detects stale controllers by checking heartbeat age — controllers that haven't reported in over 10 minutes are marked as stale and dimmed in the UI.

## Multi-Cluster Setup

To run Controllers across multiple Kubernetes clusters reporting to the same OpenLIT dashboard, set a unique `cluster_id` for each cluster:

```yaml theme={null}
# Cluster A
cluster_id: "us-east-prod"

# Cluster B
cluster_id: "eu-west-prod"
```

Services from different clusters will appear on the Agents page with their cluster label, and desired states are scoped per cluster.
