---
# yaml-language-server: $schema=./values.schema.json

# -- Options applied to every pod created by this chart.
defaultPodOptions:
  # -- RuntimeClass exposing the GPU to the pod (e.g. "nvidia"). Leave empty
  #    for CPU-only clusters. When set, the NVIDIA_* env vars on the ollama
  #    container enable GPU acceleration.
  runtimeClassName: ""
  # Ollama does not call the Kubernetes API (5.x default).
  automountServiceAccountToken: false
  # -- Pin the workload to specific node(s), typically a GPU host.
  nodeSelector: {}
    # kubernetes.io/hostname: gpu-worker

controllers:
  main:
    type: deployment
    # Single RWO PVC: recreate the pod on upgrade so the new one can mount
    # the volume only after the old one has released it.
    strategy: Recreate
    pod:
      # -- Extra pod labels. Example for Sablier scale-to-zero on a GPU group:
      labels: {}
        # sablier.enable: "true"
        # sablier.group: gpu
    containers:
      ollama:
        image:
          # -- Ollama server image.
          repository: ollama/ollama
          # -- Image tag. Pin to a release (e.g. "0.6.0") for reproducibility.
          tag: latest
          pullPolicy: Always
        env:
          # -- Bind on all interfaces so the Service and the exporter sidecar
          #    can reach Ollama. Never set this to 127.0.0.1 in-cluster.
          OLLAMA_HOST: "0.0.0.0"
          # -- Allowed CORS origins.
          OLLAMA_ORIGINS: "*"
          # Performance/tuning knobs left to Ollama's own upstream defaults.
          # Uncomment and adjust to your hardware and workload:
          # -- How long a model stays loaded in memory after the last request.
          # OLLAMA_KEEP_ALIVE: 30m
          # -- Number of parallel requests handled per model.
          # OLLAMA_NUM_PARALLEL: "2"
          # -- Maximum number of models kept loaded simultaneously.
          # OLLAMA_MAX_LOADED_MODELS: "4"
          # -- Spread work across all GPUs.
          # OLLAMA_SCHED_SPREAD: "1"
          # -- Enable Flash Attention.
          # OLLAMA_FLASH_ATTENTION: "true"
          # -- Disable prompt history persistence.
          OLLAMA_NOHISTORY: "true"
          # -- Scratch directory (mounted as an emptyDir below).
          OLLAMA_TMPDIR: /tmp/ollama
          # GPU exposure — effective only when defaultPodOptions.runtimeClassName
          # is set to an NVIDIA RuntimeClass.
          NVIDIA_VISIBLE_DEVICES: all
          NVIDIA_DRIVER_CAPABILITIES: compute,utility
        probes:
          liveness:
            enabled: true
            custom: true
            spec:
              httpGet:
                path: /
                port: 11434
              initialDelaySeconds: 30
              periodSeconds: 15
              timeoutSeconds: 5
              failureThreshold: 6
          readiness:
            enabled: true
            custom: true
            spec:
              httpGet:
                path: /
                port: 11434
              initialDelaySeconds: 10
              periodSeconds: 10
              timeoutSeconds: 5
              failureThreshold: 6
          startup:
            enabled: false
        resources:
          requests:
            cpu: 100m
            # -- Bump to match the models you intend to serve (e.g. 10Gi).
            memory: 2Gi
          # limits:
          #   memory: 16Gi

      # -- Prometheus exporter / transparent proxy sidecar. Listens on :8000,
      #    exposes /metrics, and forwards API requests to the Ollama server in
      #    the same pod, so the http Service port targets :8000 (see service
      #    below). Source: https://github.com/frcooper/ollama-exporter (Unlicense).
      exporter:
        # -- Single switch for the whole metrics/proxy path. Set to false to
        #    drop the sidecar: the chart then routes the http Service port
        #    straight to Ollama (11434) and disables the metrics port. No
        #    other value needs changing (handled in templates/common.yaml).
        enabled: true
        dependsOn: ollama
        image:
          # -- Exporter image. Multi-arch build published to GHCR and signed
          #    with cosign (keyless). Repoint to ghcr.io/frcooper/ollama-exporter
          #    if the upstream build workflow is merged there.
          repository: ghcr.io/obeone/ollama-exporter
          # -- Image tag. Pin to a released version once tags are published.
          tag: latest
          pullPolicy: Always
        env:
          # -- Upstream Ollama URL the exporter proxies to (same pod, localhost).
          OLLAMA_HOST: http://localhost:11434
        ports:
          - name: proxy
            containerPort: 8000
        probes:
          # Liveness stays a cheap "is the process alive" check on /metrics, but
          # tolerant (5s timeout, 6 failures) so a proxy busy streaming a long
          # generation is not killed mid-flight.
          liveness:
            enabled: true
            custom: true
            spec:
              httpGet:
                path: /metrics
                port: 8000
              initialDelaySeconds: 15
              periodSeconds: 30
              timeoutSeconds: 5
              failureThreshold: 6
          # Readiness probes the REAL pass-through: GET /api/version is forwarded
          # through the proxy to Ollama, so the pod is "Ready" only when the whole
          # exporter -> Ollama chain answers. A /metrics-only probe went green even
          # when Ollama behind it was unreachable, silently blackholing the API.
          readiness:
            enabled: true
            custom: true
            spec:
              httpGet:
                path: /api/version
                port: 8000
              initialDelaySeconds: 10
              periodSeconds: 10
              timeoutSeconds: 5
              failureThreshold: 3
              successThreshold: 1
          # Startup gate: give a cold start ~60s (12 x 5s) before liveness bites.
          startup:
            enabled: true
            custom: true
            spec:
              httpGet:
                path: /metrics
                port: 8000
              initialDelaySeconds: 5
              periodSeconds: 5
              failureThreshold: 12
        # This sidecar sits in the DATA PATH (Service http:11434 -> proxy:8000 ->
        # Ollama:11434), so it is a single point of failure for the whole API.
        # 10m/32Mi was starvation-grade for a uvicorn reverse proxy carrying every
        # streamed token: undersizing => OOMKill => API outage. These are sane
        # baselines; raise them in your own values for heavy concurrent workloads.
        # Sizing it well lowers the SPOF risk but does not remove it -- disable the
        # sidecar (exporter.enabled: false) to serve the API straight from Ollama.
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            # CPU limit is a burst ceiling; drop it if you observe CFS throttling
            # on the proxy (the memory limit is the real guard against OOM).
            cpu: 500m
            memory: 512Mi

service:
  main:
    controller: main
    type: ClusterIP
    ports:
      http:
        primary: true
        port: 11434
        protocol: HTTP
        targetPort: proxy

ingress:
  main:
    enabled: false
    className: ""
    # -- Ingress annotations. Example Traefik whitelist middleware:
    annotations: {}
      # traefik.ingress.kubernetes.io/router.middlewares: traefik-localnet-whitelist@kubernetescrd
    hosts:
      - host: chart-example.local
        paths:
          - path: /
            pathType: Prefix
            service:
              identifier: main
              # Route the ingress to the proxied API port (11434 -> exporter
              # :8000 -> Ollama), not the raw /metrics scrape port.
              port: http
    tls: []
      # - secretName: chart-example-tls
      #   hosts:
      #     - chart-example.local

# -- Gateway API HTTPRoute, mirroring the Ingress above. Disabled by default:
# pick either Ingress or HTTPRoute, not both. Requires the Gateway API CRDs and
# an existing Gateway in the cluster.
route:
  main:
    # -- Enable the HTTPRoute. Mutually exclusive with `ingress.main.enabled`.
    enabled: false
    # -- Route kind. HTTPRoute, GRPCRoute, TCPRoute, TLSRoute or UDPRoute.
    kind: HTTPRoute
    # -- Gateways this route attaches to.
    parentRefs:
      - name: gateway
        namespace: gateway-system
        # -- Listener name on the Gateway. Optional.
        # sectionName: https
    # -- Hostnames served by this route.
    hostnames:
      - chart-example.local
    # -- Routing rules. `identifier` refers to a Service defined above.
    rules:
      - matches:
          - path:
              type: PathPrefix
              value: /
        backendRefs:
          - identifier: main
            # Route to the proxied API port (11434 -> exporter :8000 -> Ollama),
            # not the raw /metrics scrape port, same as the Ingress above.
            port: http

persistence:
  # Ollama model/blob store. Mounted only into the ollama container.
  data:
    enabled: true
    type: persistentVolumeClaim
    accessMode: ReadWriteOnce
    size: 100Gi
    # storageClass: ""
    # -- Reuse a pre-created PVC instead of provisioning a new one.
    # existingClaim: ollama
    advancedMounts:
      main:
        ollama:
          - path: /root/.ollama
  # Scratch space for OLLAMA_TMPDIR. Mounted only into the ollama container.
  tmp:
    enabled: true
    type: emptyDir
    advancedMounts:
      main:
        ollama:
          - path: /tmp/ollama

# -- Prometheus Operator ServiceMonitor scraping the exporter's /metrics.
#    Disabled by default; enable it (or set it in your override) when a
#    Prometheus Operator stack is present.
serviceMonitor:
  metrics:
    enabled: false
    serviceName: ''
    endpoints:
      - port: http
        path: /metrics
        interval: 30s
        scrapeTimeout: 10s
