# CleverAgents Kubernetes Deployment

This directory contains the Helm chart for deploying the CleverAgents server to
Kubernetes. The chart provisions a Deployment, Service, and optional Ingress with
TLS termination, following the architecture described in the project specification.

## Prerequisites

- Kubernetes cluster (v1.24+)
- Helm 3.x
- Container image built from `Dockerfile.server` at the repository root
- PostgreSQL database (managed or self-hosted) for server persistence
- (Optional) Redis for multi-instance session affinity and rate limiting

## Helm Dependency Setup

This chart declares Redis as an optional Helm dependency. Before running
`helm lint`, `helm template`, `helm install`, or `helm upgrade`, prepare chart
dependencies:

```bash
# Rebuild from Chart.lock/charts if present
helm dependency build ./k8s

# Or refresh dependency versions from upstream repositories
helm dependency update ./k8s
```

## Quick Start

### 1. Build the Server Image

```bash
docker build -f Dockerfile.server -t cleveragents/server:1.0.0 .
```

Then configure the chart to use the same tag:

```bash
helm upgrade --install cleveragents ./k8s \
  --set image.repository=cleveragents/server \
  --set image.tag=1.0.0
```

### 2. Install the Chart

Build/update dependencies first:

```bash
helm dependency build ./k8s
```

Create a Kubernetes Secret for the database URL (recommended):

```bash
kubectl create secret generic cleveragents-db \
  --from-literal=database-url="postgresql+asyncpg://user:pass@db-host:5432/cleveragents"
```

Install the chart referencing that secret:

```bash
helm install cleveragents ./k8s \
  --set database.existingSecret=cleveragents-db \
  --set database.existingSecretKey=database-url
```

### 3. Verify the Deployment

```bash
kubectl get pods -l app.kubernetes.io/name=cleveragents
kubectl get svc cleveragents
```

## Configuration

All configuration is managed through `values.yaml`. Override values at install
time using `--set` flags or a custom values file (`-f custom-values.yaml`).

### Key Configuration Options

| Parameter | Description | Default |
|---|---|---|
| `replicaCount` | Number of server replicas | `1` |
| `image.repository` | Container image repository | `cleveragents/server` |
| `image.tag` | Image tag (defaults to appVersion) | `""` |
| `resources.limits.cpu` | CPU limit | `500m` |
| `resources.limits.memory` | Memory limit | `512Mi` |
| `resources.requests.cpu` | CPU request | `100m` |
| `resources.requests.memory` | Memory request | `128Mi` |
| `ingress.enabled` | Enable Ingress | `false` |
| `ingress.allowInsecure` | Allow HTTP-only ingress (dev-only) | `false` |
| `ingress.className` | Ingress class name | `""` |
| `ingress.tls` | TLS configuration | `[]` |
| `redis.enabled` | Enable Redis subchart | `false` |
| `database.url` | PostgreSQL connection URL | `""` |
| `database.existingSecret` | Secret name for DB URL | `""` |
| `server.workers` | Uvicorn worker count | `1` |
| `server.logLevel` | Server log level | `info` |

### Health Probes

The chart uses separate probe endpoints by default:

- **Liveness** (`livenessProbe.httpGet.path`): `/live`
- **Readiness** (`readinessProbe.httpGet.path`): `/ready`

This split lets operators configure independent probe timing and failure
thresholds. In the current implementation, readiness is process-level and does
not yet perform dependency checks (for example live DB/Redis connectivity).

### Scaling

Scale the deployment by adjusting `replicaCount`:

```bash
helm dependency build ./k8s
helm upgrade cleveragents ./k8s --set replicaCount=3
```

When running multiple replicas, enable Redis for session affinity:

```bash
helm dependency build ./k8s
helm upgrade cleveragents ./k8s \
  --set replicaCount=3 \
  --set redis.enabled=true \
  --set redis.auth.existingSecret=cleveragents-redis \
  --set redis.auth.existingSecretPasswordKey=redis-password
```

### TLS Configuration

Enable Ingress with TLS termination for production deployments:

```bash
helm dependency build ./k8s
helm upgrade cleveragents ./k8s \
  --set ingress.enabled=true \
  --set ingress.className=nginx \
  --set ingress.hosts[0].host=cleveragents.example.com \
  --set ingress.hosts[0].paths[0].path=/ \
  --set ingress.hosts[0].paths[0].pathType=Prefix \
  --set ingress.tls[0].secretName=cleveragents-tls \
  --set ingress.tls[0].hosts[0]=cleveragents.example.com \
  --set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod
```

TLS termination occurs at the Kubernetes Ingress controller level. The
CleverAgents server itself communicates over plain HTTP within the cluster.

By default, the chart **fails rendering** if `ingress.enabled=true` and
`ingress.tls` is not configured. For local-only development, you can explicitly
opt out by setting `ingress.allowInsecure=true`.

```bash
helm dependency build ./k8s
helm upgrade cleveragents ./k8s \
  --set ingress.enabled=true \
  --set ingress.allowInsecure=true
```

### Database Configuration

The server requires a database connection. For production, use a Kubernetes
Secret and set `database.existingSecret`.

The chart requires **one** of:

- `database.existingSecret` (recommended)
- `database.url` (allowed for local/dev convenience)

Examples:

```yaml
# Direct URL
database:
  url: "postgresql+asyncpg://user:password@postgres-host:5432/cleveragents"

# Using an existing Secret
database:
  existingSecret: "cleveragents-db-credentials"
  existingSecretKey: "database-url"
```

### Redis (Optional)

Redis support in this chart is currently **infrastructure scaffolding**:

- The chart can provision Redis (Bitnami subchart) and inject Redis-related
  environment variables into the server Deployment.
- The current server runtime does **not** yet implement Redis-backed session
  affinity/rate-limiting behavior end-to-end.

Use this section to provision Redis infrastructure now; runtime integration is a
follow-up capability.

Redis is deployed as a subchart from the Bitnami Helm repository:

```yaml
redis:
  enabled: true
  architecture: standalone
  auth:
    enabled: true
    existingSecret: "redis-credentials"
    existingSecretPasswordKey: "redis-password"
  master:
    persistence:
      enabled: true
      size: 2Gi
```

## Resource Limits

Default resource limits are conservative. Adjust based on expected load:

```yaml
resources:
  limits:
    cpu: "2"
    memory: 2Gi
  requests:
    cpu: 500m
    memory: 512Mi
```

## Architecture

The Helm chart deploys the following Kubernetes resources:

- **Deployment**: Runs the CleverAgents ASGI server with configurable replicas
  and writable volumes for `/tmp` and `/app/data`
- **Service**: ClusterIP service exposing the server port (8000)
- **Ingress** (optional): Routes external traffic with TLS termination
- **ConfigMap**: Server configuration environment variables
- **ServiceAccount**: Dedicated service account for pod identity
- **Secrets**: Auto-generated secrets for database URL and Redis password
  (when `existingSecret` is not configured)
- **Redis** (optional): Bitnami Redis subchart for session affinity

The server container runs as a non-root user (`appuser`, uid 1000) with a
read-only root filesystem for security hardening. Writable `emptyDir` volumes
are mounted at `/tmp` and `/app/data` to support runtime operations.

## Uninstalling

```bash
helm uninstall cleveragents
```
