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

# Kubernetes Deployment

> Deploy Corbulo on Kubernetes

# Kubernetes Deployment

This guide covers deploying Corbulo on Kubernetes for production environments that need scaling, high availability, and operational maturity. This is the recommended approach for teams with 50+ developers or when uptime requirements are critical.

***

## Prerequisites

* Kubernetes 1.28+
* Helm 3.x
* `kubectl` configured for your cluster
* PostgreSQL 16+ (managed or self-hosted)
* Redis 7+ (managed or self-hosted)
* FalkorDB instance
* Temporal server
* A registered GitHub App (see [GitHub Integration](/integrations/github))
* A Clerk account for authentication
* Access to an OpenAI-compatible AI model API

<Note>
  For production deployments, use managed database services (e.g., Amazon RDS, Cloud SQL, Azure Database) rather than running PostgreSQL and Redis inside the cluster.
</Note>

***

## Quick Start

<Steps>
  <Step title="Add the Corbulo Helm repository">
    ```bash theme={null}
    helm repo add corbulo https://charts.corbulo.dev
    helm repo update
    ```
  </Step>

  <Step title="Create a namespace">
    ```bash theme={null}
    kubectl create namespace corbulo
    ```
  </Step>

  <Step title="Create secrets">
    Store sensitive configuration in Kubernetes secrets:

    ```bash theme={null}
    kubectl create secret generic corbulo-config \
      --namespace corbulo \
      --from-literal=DATABASE_URL='postgres://user:pass@host:5432/corbulo?sslmode=require' \
      --from-literal=REDIS_URL='redis://host:6379' \
      --from-literal=SECRET_KEY='your-secret-key' \
      --from-literal=CLERK_SECRET_KEY='your-clerk-secret' \
      --from-literal=GITHUB_WEBHOOK_SECRET='your-webhook-secret' \
      --from-literal=LLM_OPENAI_LARGE_API_KEY='your-api-key' \
      --from-literal=LLM_OPENAI_SMALL_API_KEY='your-api-key'

    kubectl create secret generic github-private-key \
      --namespace corbulo \
      --from-file=github-app.pem=/path/to/your/private-key.pem
    ```
  </Step>

  <Step title="Create a values file">
    Create `values.yaml` with your configuration. See the [values reference](#valuesyaml-reference) below.
  </Step>

  <Step title="Install the chart">
    ```bash theme={null}
    helm install corbulo corbulo/corbulo \
      --namespace corbulo \
      --values values.yaml
    ```
  </Step>

  <Step title="Run database migrations">
    ```bash theme={null}
    kubectl exec -n corbulo deploy/corbulo-api -- corbulo migrate up
    ```
  </Step>

  <Step title="Verify the deployment">
    ```bash theme={null}
    kubectl exec -n corbulo deploy/corbulo-api -- curl -s http://localhost:8080/healthz
    ```
  </Step>
</Steps>

***

## values.yaml Reference

```yaml theme={null}
# Corbulo Helm chart values

global:
  image:
    repository: ghcr.io/corbulo/corbulo-api
    tag: latest
    pullPolicy: Always

# API Server
api:
  replicas: 2
  port: 8080
  resources:
    requests:
      cpu: 500m
      memory: 512Mi
    limits:
      cpu: 2000m
      memory: 2Gi
  env:
    APP_ENV: production
    LOG_LEVEL: info
    TEMPORAL_ADDRESS: temporal.temporal:7233
    FALKORDB_HOST: falkordb.corbulo:6379
    CLERK_JWT_ISSUER: https://your-clerk-instance.clerk.accounts.dev
    GITHUB_APP_ID: "123456"
    GITHUB_PRIVATE_KEY_PATH: /keys/github-app.pem
    FRONTEND_URL: https://corbulo.yourcompany.com
    BACKEND_URL: https://api.corbulo.yourcompany.com
    CORS_ORIGINS: https://corbulo.yourcompany.com
    LLM_OPENAI_LARGE_PROVIDER: openai
    LLM_OPENAI_LARGE_MODEL: gpt-4o
    LLM_OPENAI_LARGE_BASE_URL: https://api.openai.com/v1
    LLM_OPENAI_SMALL_PROVIDER: openai
    LLM_OPENAI_SMALL_MODEL: gpt-4o-mini
    LLM_OPENAI_SMALL_BASE_URL: https://api.openai.com/v1
  envFromSecret: corbulo-config
  volumeMounts:
    - name: github-key
      mountPath: /keys
      readOnly: true
  volumes:
    - name: github-key
      secret:
        secretName: github-private-key
  service:
    type: ClusterIP
    port: 8080
  ingress:
    enabled: true
    className: nginx
    hosts:
      - host: api.corbulo.yourcompany.com
        paths:
          - path: /
            pathType: Prefix
    tls:
      - secretName: corbulo-api-tls
        hosts:
          - api.corbulo.yourcompany.com

# Analysis Workers
worker:
  replicas: 2
  resources:
    requests:
      cpu: 1000m
      memory: 1Gi
    limits:
      cpu: 4000m
      memory: 4Gi
  env:
    AGENT_EXECUTION_MODE: k8s
    K8S_AGENT_NAMESPACE: corbulo
  envFromSecret: corbulo-config
  volumeMounts:
    - name: github-key
      mountPath: /keys
      readOnly: true
  volumes:
    - name: github-key
      secret:
        secretName: github-private-key

# Frontend
frontend:
  replicas: 2
  image:
    repository: ghcr.io/corbulo/corbulo-frontend
    tag: latest
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 256Mi
  service:
    type: ClusterIP
    port: 80
  ingress:
    enabled: true
    className: nginx
    hosts:
      - host: corbulo.yourcompany.com
        paths:
          - path: /
            pathType: Prefix
    tls:
      - secretName: corbulo-frontend-tls
        hosts:
          - corbulo.yourcompany.com

# Monitoring
metrics:
  enabled: true
  serviceMonitor:
    enabled: true
    interval: 30s
    path: /metrics
    port: 8080
```

***

## Scaling

### Horizontal Scaling

The API server and workers scale independently. Workers are the primary scaling target -- add more replicas to process analysis tasks faster.

```bash theme={null}
# Scale workers for higher analysis throughput
kubectl scale deploy corbulo-worker -n corbulo --replicas=5

# Scale API for higher request throughput
kubectl scale deploy corbulo-api -n corbulo --replicas=4
```

### Horizontal Pod Autoscaler

```yaml theme={null}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: corbulo-worker
  namespace: corbulo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: corbulo-worker
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
```

### Resource Sizing Guide

| Team Size   | API Replicas | Worker Replicas | Worker CPU | Worker Memory |
| ----------- | ------------ | --------------- | ---------- | ------------- |
| 10-50 devs  | 2            | 2               | 1000m      | 1 Gi          |
| 50-200 devs | 3            | 4               | 2000m      | 2 Gi          |
| 200+ devs   | 4+           | 6+              | 2000m      | 4 Gi          |

***

## High Availability

### API Server

Run at least 2 replicas with pod anti-affinity to spread across nodes:

```yaml theme={null}
api:
  replicas: 2
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: corbulo-api
            topologyKey: kubernetes.io/hostname
```

### Workers

Workers are stateless and can tolerate pod restarts. Temporal automatically retries tasks assigned to workers that go down. Run at least 2 replicas in production.

### Infrastructure Services

For high availability of infrastructure services:

* **PostgreSQL**: Use a managed service with automated failover (Amazon RDS, Cloud SQL, Azure Database).
* **Redis**: Use a managed service with replication (ElastiCache, Memorystore, Azure Cache).
* **Temporal**: Deploy the Temporal server cluster with multiple history and matching service replicas.
* **FalkorDB**: Run with persistent storage and regular backups.

***

## Operations

### Health Checks

The Helm chart configures liveness and readiness probes automatically. The health endpoints are:

| Endpoint           | Purpose                                                                                                                         |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `/healthz`         | Simple health check. Returns 200 if the service is running. Used for liveness probes.                                           |
| `/health/detailed` | Component health check. Returns status of each infrastructure dependency with circuit breaker state. Used for readiness probes. |

### Monitoring

Corbulo exposes Prometheus metrics at `/metrics` on port 8080. The Helm chart can create a `ServiceMonitor` for automatic Prometheus discovery.

Key metrics to monitor:

* HTTP request latency and error rates
* Active Temporal workflow counts
* Analysis task duration and failure rates
* Database connection pool utilization

OpenTelemetry tracing is supported via standard `OTEL_*` environment variables. Enable it in your values:

```yaml theme={null}
api:
  env:
    OTEL_ENABLED: "true"
    OTEL_ENDPOINT: "otel-collector.monitoring:4317"
```

### Logs

All components write structured JSON logs to stdout. Use your cluster's log aggregation pipeline (Fluentd, Loki, CloudWatch Logs, etc.) to collect and search logs.

```bash theme={null}
# View API logs
kubectl logs -n corbulo -l app=corbulo-api -f

# View worker logs
kubectl logs -n corbulo -l app=corbulo-worker -f
```

### Upgrades

```bash theme={null}
# Update Helm repository
helm repo update

# Upgrade to latest version
helm upgrade corbulo corbulo/corbulo \
  --namespace corbulo \
  --values values.yaml

# Run any new migrations after upgrade
kubectl exec -n corbulo deploy/corbulo-api -- corbulo migrate up
```

### Backups

Back up the PostgreSQL database regularly using your managed service's backup features or `pg_dump`. Redis and FalkorDB contain derived data that can be reconstructed from a fresh analysis run.

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Pods stuck in CrashLoopBackOff">
    Check the pod logs for the specific error:

    ```bash theme={null}
    kubectl logs -n corbulo deploy/corbulo-api --previous
    ```

    The most common causes are missing environment variables (the application logs which variable is unset) or unreachable infrastructure services.
  </Accordion>

  <Accordion title="Readiness probe failing">
    The readiness probe calls `/health/detailed`, which checks connectivity to all infrastructure services. Identify which component is unhealthy:

    ```bash theme={null}
    kubectl exec -n corbulo deploy/corbulo-api -- curl -s http://localhost:8080/health/detailed | jq .
    ```

    The response includes the status of each dependency (PostgreSQL, Redis, FalkorDB, Temporal).
  </Accordion>

  <Accordion title="Workers not picking up tasks">
    Verify workers are connected to Temporal and the correct namespace:

    ```bash theme={null}
    kubectl logs -n corbulo -l app=corbulo-worker --tail=50
    ```

    Confirm that `TEMPORAL_ADDRESS` and `TEMPORAL_NAMESPACE` match between the API and worker deployments.
  </Accordion>

  <Accordion title="Ingress not routing traffic">
    Verify the ingress resource is created and has an address assigned:

    ```bash theme={null}
    kubectl get ingress -n corbulo
    ```

    Confirm your DNS records point to the ingress controller's external IP or load balancer. Check the ingress controller logs if requests are not reaching the Corbulo pods.
  </Accordion>

  <Accordion title="Analysis tasks timing out">
    Analysis task duration depends on repository size and AI model response time. If tasks are timing out:

    1. Check AI model API latency -- slow responses from the model provider are the most common cause.
    2. Scale workers to reduce queue depth.
    3. Verify workers have sufficient memory -- large repositories require more memory during analysis.
  </Accordion>
</AccordionGroup>
