Skip to content

langfuse/langfuse-k8s

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub Banner

langfuse-k8s

Artifact Hub

This is a community-maintained repository that contains resources for deploying Langfuse on Kubernetes. Please feel free to contribute any improvements or suggestions.

Langfuse self-hosting documentation: https://langfuse.com/self-hosting

Repository Structure

  • examples directory contains example yaml configurations
  • charts/langfuse directory contains Helm chart for deploying Langfuse with an associated database

Helm Chart

We provide a Helm chart that helps you deploy Langfuse on Kubernetes.

Installation

Configure the required secrets and parameters as defined below in a new values.yaml file. Then install the helm chart using the commands below:

helm repo add langfuse https://langfuse.github.io/langfuse-k8s
helm repo update
helm install langfuse langfuse/langfuse -f values.yaml

Upgrading

helm repo update
helm upgrade langfuse langfuse/langfuse

Please validate whether the helm sub-charts in the Chart.yaml were updated between versions. If yes, follow the guide for the respective sub-chart to upgrade it.

Sizing

By default, the chart will run with the minimum resources to provide a stable experience. For production environments, we recommend to adjust the following parameters in the values.yaml. See Langfuse documentation for our full sizing guide.

langfuse:
  resources:
    limits:
      cpu: "2"
      memory: "4Gi"
    requests:
      cpu: "2"
      memory: "4Gi"

clickhouse:
  resources:
    limits:
      cpu: "2"
      memory: "8Gi"
    requests:
      cpu: "2"
      memory: "8Gi"
      
  keeper:
    resources:
      limits:
        cpu: "2"
        memory: "4Gi"
      requests:
        cpu: "2"
        memory: "4Gi"

redis:
  primary:
    resources:
      limits:
        cpu: "1"
        memory: "1.5Gi"
      requests:
        cpu: "1"
        memory: "1.5Gi"

s3:
  resources:
    limits:
      cpu: "2"
      memory: "4Gi"
    requests:
      cpu: "2"
      memory: "4Gi"

Configuration

The required configuration options to set are:

# Optional, but highly recommended. Generate via `openssl rand -hex 32`.
#  langfuse:
#    encryptionKey:
#      value: ""
langfuse: 
  salt:
    value: secureSalt
  nextauth:
    secret:
      value: ""

postgresql:
  auth:
    # If you want to use `postgres` as the username, you need to provide postgresPassword instead of password.
    username: langfuse
    password: ""

clickhouse:
  auth:
    password: ""

redis:
  auth:
    password: ""

s3:
  auth:
    rootPassword: ""

They can alternatively set via secret references (the secrets must exist):

# Optional, but highly recommended. Generate via `openssl rand -hex 32`.
#  langfuse:
#    encryptionKey:
#      secretKeyRef:
#        name: langfuse-encryption-key-secret
#        key: encryptionKey
langfuse: 
  salt:
    secretKeyRef:
      name: langfuse-general
      key: salt
  nextauth:
    secret:
      secretKeyRef:
        name: langfuse-nextauth-secret
        key: nextauth-secret

postgresql:
  auth:
    # If you want to use `postgres` as the username, you need to provide a adminPasswordKey in secretKeys.
    username: langfuse
    existingSecret: langfuse-postgresql-auth
    secretKeys:
      userPasswordKey: password

clickhouse:
  auth:
    existingSecret: langfuse-clickhouse-auth
    existingSecretKey: password

redis:
  auth:
    existingSecret: langfuse-redis-auth
    existingSecretPasswordKey: password

s3:
  auth:
    # If existingSecret is set, both root user and root password must be supplied via the secret
    existingSecret: langfuse-s3-auth
    rootUserSecretKey: rootUser
    rootPasswordSecretKey: rootPassword

See the Helm README for a full list of all configuration options.

Examples:

With an external Postgres server
[...]
postgresql:
  deploy: false
  auth:
    username: my-username
    password: my-password
    database: my-database
  host: my-external-postgres-server.com
  directUrl: postgres://my-username:my-password@my-external-postgres-server.com
  shadowDatabaseUrl: postgres://my-username:my-password@my-external-postgres-server.com

With an external S3 bucket

[...]
s3:
  deploy: false
  bucket: "langfuse-bucket"
  region: "eu-west-1"
  endpoint: "https://s3.eu-west-1.amazonaws.com"
  forcePathStyle: false
  accessKeyId:
    value: "mykey"
  secretAccessKey:
    value: "mysecret"
  eventUpload:
    prefix: "events/"
  batchExport:
    prefix: "exports/"
  mediaUpload:
    prefix: "media/"

Use custom deployment strategy

[...]
langfuse:
  deployment:
    strategy:
      type: RollingUpdate
      rollingUpdate:
        maxSurge: 50%
        maxUnavailable: 50%
Enable ingress
[...]
langfuse:
  ingress:
    enabled: true
    hosts:
    - host: langfuse.your-host.com
      paths:
      - path: /
        pathType: Prefix
    annotations: []

Custom Storage Class Definition

The Langfuse chart supports configuring storage classes for all persistent volumes in the deployment. You can configure storage classes in two ways:

  1. Global Storage Class: Set a global storage class that will be used for all persistent volumes unless overridden.
global:
  defaultStorageClass: "your-storage-class"
  1. Component-specific Storage Classes: Override the storage class for specific components.
postgresql:
  primary:
    persistence:
      storageClass: "postgres-storage-class"
   
redis:
  primary:
    persistence:
      storageClass: "redis-storage-class"

clickhouse:
  persistence:
    storageClass: "clickhouse-storage-class"

s3:
  persistence:
    storageClass: "minio-storage-class"

If no storage class is specified, the cluster's default storage class will be used.

With an external Postgres server with client certificates using own secrets and additionalEnv for mappings
langfuse:
  salt: null
  nextauth: 
    secret: null
  extraVolumes:
    - name: db-keystore   # referencing an existing secret to mount server/client certs for postgres
      secret:
        secretName: langfuse-postgres  # contain the following files (server-ca.pem, sslidentity.pk12)
  extraVolumeMounts:
    - name: db-keystore
      mountPath: /secrets/db-keystore  # mounting the db-keystore store certs in the pod under the given path
      readOnly: true
  additionalEnv:
    - name: DATABASE_URL  # Using the certs in the url eg. postgresql://the-db-user:the-password@postgres-host:5432/langfuse?ssl=true&sslmode=require&sslcert=/secrets/db-keystore/server-ca.pem&sslidentity=/secrets/db-keystore/sslidentity.pk12&sslpassword=the-ssl-identity-pw
      valueFrom:
        secretKeyRef:
          name: langfuse-postgres  # referencing an existing secret
          key: database-url
    - name: NEXTAUTH_SECRET
      valueFrom:
        secretKeyRef:
          name: langfuse-general # referencing an existing secret
          key: nextauth-secret
    - name: SALT
      valueFrom:
        secretKeyRef:
          name: langfuse-general
          key: salt
service:
  [...]
ingress:
  [...]
postgresql:
  deploy: false
  auth:
    password: null
    username: null
With SSO provider configuration using secrets and additionalEnv

This example shows how to configure Okta SSO by setting the required environment variables from secrets using the additionalEnv pattern:

langfuse:
  additionalEnv:
    - name: AUTH_OKTA_CLIENT_ID
      valueFrom:
        secretKeyRef:
          name: okta-secrets
          key: AUTH_OKTA_CLIENT_ID
    - name: AUTH_OKTA_CLIENT_SECRET
      valueFrom:
        secretKeyRef:
          name: okta-secrets
          key: AUTH_OKTA_CLIENT_SECRET
    - name: AUTH_OKTA_ISSUER
      valueFrom:
        secretKeyRef:
          name: okta-secrets
          key: AUTH_OKTA_ISSUER

You would need to create the corresponding secret:

apiVersion: v1
kind: Secret
metadata:
  name: okta-secrets
type: Opaque
stringData:
  AUTH_OKTA_CLIENT_ID: "your-okta-client-id"
  AUTH_OKTA_CLIENT_SECRET: "your-okta-client-secret"
  AUTH_OKTA_ISSUER: "https://your-domain.okta.com"

This pattern works for any SSO provider supported by Langfuse. See the Authentication and SSO documentation for other providers and their required environment variables.

With overrides for hostAliases

This is going to add a record to the /etc/hosts file of all containers under the langfuse-web pod in such a way that every traffic towards "oauth.id.jumpcloud.com" is going to be forwarded to the localhost network.

langfuse:
  web:
    hostAliases:
      - ip: 127.0.0.1
        hostnames:
          - "oauth.id.jumpcloud.com"
With topology spread constraints

Distribute pods evenly across different zones to improve high availability:

langfuse:
  # Global topology spread constraints applied to all langfuse pods
  pod:
    topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            app.kubernetes.io/instance: langfuse
  
  # Component-specific topology spread constraints
  web:
    pod:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: web
  
  worker:
    pod:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: worker

About

Community-maintained Kubernetes config and Helm chart for Langfuse

Resources

License

Stars

Watchers

Forks

Contributors 26

Languages