Skip to main content
This guide walks you through deploying the Genesis container to an existing AWS EKS (Elastic Kubernetes Service) cluster.
Genesis will provide you with the container image URL. Replace <container-registry-url> throughout this document with the URL provided by Genesis.

Prerequisites

AWS EKS Cluster Requirements

EKS Cluster

Kubernetes version 1.23 or higher

kubectl

Configured to access your EKS cluster

Helm 3.8+

For deploying the Genesis Helm chart

AWS CLI

Configured with appropriate credentials
Verify cluster access:
aws eks update-kubeconfig --name <cluster-name> --region <region>
kubectl get nodes  # Verify access
Verify Helm installation:
helm version

Additional Requirements

Network Access

RequirementPurpose
Outbound InternetCluster nodes must pull container images from the registry URL provided by Genesis
DNS ResolutionFor accessing external APIs (OpenAI, Databricks, etc.) if using those LLM providers

IAM Permissions

The EKS cluster node group IAM role needs the following permissions:
  • AmazonEKSWorkerNodePolicy
  • AmazonEKS_CNI_Policy
  • AmazonEC2ContainerRegistryReadOnly
If using AWS Bedrock as the LLM provider, the node group role also needs AmazonBedrockFullAccess (or appropriate scoped permissions).

EBS CSI Driver Setup

Genesis requires persistent storage for its database, git repositories, and uploaded files. The Amazon EBS CSI driver must be installed in your cluster to provision EBS volumes.
The EBS CSI driver is not automatically installed by default on standard EKS clusters (even for Kubernetes 1.23+). You must install it manually. However, if you’re using EKS Auto Mode, the EBS CSI driver is automatically included and no installation is needed.
Check if installed:
kubectl get pods -n kube-system | grep ebs-csi

Installation Instructions

Refer to the Amazon EKS User Guide for detailed EBS CSI driver installation steps, including IAM role setup and add-on installation.

Ingress Controller Setup

Genesis requires an ingress controller for external access. Choose one based on your requirements:

Genesis Container Configuration

Container Image

SettingDescription
RepositoryGenesis will provide the container image URL (e.g., <container-registry-url>/genesis)
TagsGenesis will specify the appropriate tag to use (typically latest or a specific version)
Registry AccessGenesis will provide details about authentication requirements, if any

Image Pull Secrets (If Required)

If the container registry requires authentication, Genesis will provide the necessary credentials. Create a Kubernetes secret:
# Create namespace first if it doesn't exist
kubectl create namespace genesis

# Create Docker registry secret (if credentials provided by Genesis)
kubectl create secret docker-registry genesis-registry-credentials \
  --docker-server=<container-registry-url> \
  --docker-username=<username> \
  --docker-password=<password> \
  --docker-email=<email> \
  -n genesis
Then reference it in your Helm values file:
imagePullSecrets:
  - name: genesis-registry-credentials

Exposed Ports

PortServiceDescription
8080FastAPIPrimary application with React GUI and modern APIs
8082FlaskUDF proxy, OAuth, external integrations
8501StreamlitLegacy Streamlit interface

Persistent Storage Requirements

Genesis requires persistent storage for:
PathPurpose
/app/.genesis/db/genesis.dbSQLite database
/app/bot_gitCloned git repositories
/app/bot_storageUploaded files and bot storage
/app/tmpRuntime temp files
Recommended Storage Size: 50Gi minimum (adjust based on expected usage)Storage Class: Uses cluster default (typically gp2 or gp3 on EKS)

Environment Variables

VariableDefaultDescription
SQLITE_DB_PATH/app/.genesis/db/genesis.dbPath to SQLite database
DATABASE_URLsqlite:///app/.genesis/db/genesis.dbSQLite connection string
BOT_OS_DEFAULT_LLM_ENGINE: "litellm"  # Optional: helps with initial Bedrock setup
LITELLM_MODEL: "bedrock/<model-id>"
AWS_REGION: "<aws-region>"
AWS_DEFAULT_REGION: "<aws-region>"
# Note: Uses IAM role credentials from node group, no API key needed
VariableValueDescription
AUTH_ENABLED"true"Enable authentication
AUTH_PROVIDER"proxy"For ingress-based auth
VariableOptionsDescription
LOG_LEVELDEBUG, INFO, WARNING, ERRORLog verbosity
LOGS_FORMATjson, textLog output format

Deployment Steps

1

Prepare Helm Chart

Genesis will provide you with the Helm chart as an archive file. Extract it:
# Extract the Helm chart archive provided by Genesis
tar -xzf genesis-<version>.tgz

# Navigate to the chart directory
cd genesis
2

Create Values File

Create a genesis-values.yaml file with your configuration:
# Genesis EKS Deployment Values

# Container image (Genesis will provide the repository URL)
image:
  repository: <container-registry-url>/genesis  # Replace with URL provided by Genesis
  tag: latest  # Use the tag specified by Genesis
  pullPolicy: IfNotPresent

# Image pull secrets (if the container registry requires authentication)
# Genesis will provide instructions if credentials are needed
# imagePullSecrets:
#   - name: genesis-registry-credentials

# Secrets - REQUIRED: Configure at least one LLM provider
secrets:
  # Master encryption key (auto-generated if not provided)
  genesisMasterKey: ""  # Optional: python -c "import secrets; print(secrets.token_hex(32))"
  
  # OpenAI configuration
  openaiApiKey: "sk-your-key-here"  # Required if using OpenAI
  
  # Databricks configuration (alternative to OpenAI)
  # databricksApiKey: ""
  # databricksBaseUrl: ""
  # databricksModelName: "databricks-claude-3-7-sonnet"

# Non-sensitive configuration
config:
  sqliteDbPath: "/app/.genesis/db/genesis.db"
  logLevel: "INFO"
  logsFormat: "json"
  authEnabled: "true"
  authProvider: "proxy"  # For ingress-based authentication
  
  # AWS Bedrock configuration (if using Bedrock)
  extraEnv:
    BOT_OS_DEFAULT_LLM_ENGINE: "litellm"  # Optional: helps with initial Bedrock setup
    LITELLM_MODEL: "bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0"
    AWS_REGION: "us-east-1"
    AWS_DEFAULT_REGION: "us-east-1"

# Resource requests
resources:
  requests:
    cpu: "2000m"
    memory: "6Gi"
  limits: {}  # No limits by default

# Persistent storage
persistence:
  storageClassName: ""  # Uses cluster default (gp2/gp3)
  size: 50Gi  # Kubernetes uses binary units (Gi = Gibibytes)
  accessMode: ReadWriteOnce

# Service configuration
service:
  type: ClusterIP
  ports:
    fastapi: 8080
    flask: 8082
    streamlit: 8501

# Ingress configuration
ingress:
  enabled: true
  className: "alb"  # For AWS Load Balancer Controller, or "nginx" for NGINX
  
  # For AWS Load Balancer Controller
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/healthcheck-path: "/api/health"
    alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP"
    alb.ingress.kubernetes.io/healthcheck-port: "8080"
    # For HTTPS, add certificate ARN:
    # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:region:account:certificate/cert-id"
  
  hosts:
    - host: genesis.yourdomain.com  # Replace with your domain
      paths:
        - path: /
          pathType: Prefix
          port: 8080
  
  # TLS configuration (if using HTTPS)
  tls: []
For NGINX Ingress Controller, use these annotations instead:
annotations:
  nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
  nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
  nginx.ingress.kubernetes.io/proxy-body-size: "100m"
3

Deploy Genesis

# Install using Helm
helm install genesis ./genesis -f genesis-values.yaml

# Or if deploying from chart directory
helm install genesis . -f genesis-values.yaml
4

Verify Deployment

# Check namespace
kubectl get namespace genesis

# Check StatefulSet
kubectl get statefulset -n genesis

# Check pod status
kubectl get pods -n genesis -w

# Check persistent volume claim
kubectl get pvc -n genesis

# Check service
kubectl get svc -n genesis

# Check ingress
kubectl get ingress -n genesis

# View pod logs
kubectl logs -n genesis genesis-0 --follow
5

Access Genesis

Kubernetes-Specific Configuration

StatefulSet

Genesis is deployed as a StatefulSet (not Deployment) to ensure:
  • Stable network identity (pod name: genesis-0)
  • Ordered, graceful deployment and scaling
  • Stable persistent storage (PVC name: genesis-data-genesis-0)

Persistent Volume Claim

The StatefulSet creates a PersistentVolumeClaim with:
PropertyValue
Namegenesis-data-genesis-0
Storage ClassUses cluster default (typically gp2 or gp3)
Access ModeReadWriteOnce (single pod access)
RetentionPVC is retained when StatefulSet is deleted (data preservation)

Volume Mounts

The Genesis container mounts the persistent volume at multiple paths:
Mount PathPurpose
/app/.genesis/dbDatabase files
/app/bot_gitGit repositories
/app/bot_storageFile storage and uploads
/app/tmpTemporary files

Health Checks

Genesis includes liveness and readiness probes:

Liveness Probe

  • Endpoint: GET /api/health on port 8080
  • Initial delay: 60 seconds
  • Period: 30 seconds
  • Timeout: 5 seconds
  • Failure threshold: 3

Readiness Probe

  • Endpoint: GET /api/health on port 8080
  • Initial delay: 30 seconds
  • Period: 10 seconds
  • Timeout: 5 seconds
  • Failure threshold: 3

Resource Requirements

Default resource requests:
ResourceRequest
CPU2000m (2 cores)
Memory6Gi
No resource limits are set by default to avoid OOM kills. Adjust based on your workload.

AWS-Specific Considerations

IAM Roles for Service Accounts (IRSA)

If using AWS Bedrock, you can configure IRSA to allow the Genesis pod to access Bedrock without storing credentials:
  1. Create IAM Role with Bedrock permissions
  2. Create Service Account with role annotation:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: genesis
  namespace: genesis
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/genesis-bedrock-role
  1. Configure StatefulSet to use the service account (modify Helm values or StatefulSet directly)

EBS Volume Encryption

EBS volumes created by the EBS CSI driver on EKS are encrypted by default if your cluster has encryption enabled. Verify:
kubectl get storageclass -o yaml

VPC Configuration

Ensure your EKS cluster nodes have:
RequirementPurpose
Outbound Internet AccessFor pulling images from the container registry provided by Genesis
DNS ResolutionFor external API calls (OpenAI, Databricks, etc.)
Security Group RulesAllow ingress on ports 80/443 if using ALB, or node port if using NodePort service

Troubleshooting

# Check pod status
kubectl describe pod -n genesis genesis-0

# Check events
kubectl get events -n genesis --sort-by='.lastTimestamp'
Common issues:
  • Image pull errors: Check network connectivity to the container registry provided by Genesis
  • PVC issues: Verify EBS CSI driver is installed and storage class exists
  • Resource constraints: Check node resources
# Check PVC status
kubectl get pvc -n genesis
kubectl describe pvc genesis-data-genesis-0 -n genesis

# Check PV
kubectl get pv
kubectl describe pv <pv-name>

# Check EBS CSI driver logs
kubectl logs -n kube-system -l app=ebs-csi-controller
For AWS Load Balancer Controller:
# Check controller logs
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

# Check ingress status
kubectl describe ingress -n genesis genesis

# Verify ALB was created
aws elbv2 describe-load-balancers --region <region>
For NGINX Ingress:
# Check controller pods
kubectl get pods -n ingress-nginx

# Check controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller
# Access pod shell
kubectl exec -it -n genesis genesis-0 -- /bin/bash

# Check database file
ls -lh /app/.genesis/db/

# Check database integrity (if SQLite tools available)
sqlite3 /app/.genesis/db/genesis.db "PRAGMA integrity_check;"
# View current logs
kubectl logs -n genesis genesis-0

# Follow logs
kubectl logs -n genesis genesis-0 --follow

# View previous container logs (if pod restarted)
kubectl logs -n genesis genesis-0 --previous

Upgrading Genesis

When a new Genesis version is released:
# Update image tag in values file or override
helm upgrade genesis ./genesis -f genesis-values.yaml --set image.tag=v1.3.2

# Or update values.yaml and upgrade
helm upgrade genesis ./genesis -f genesis-values.yaml

# Verify upgrade
kubectl get pods -n genesis -o jsonpath='{.items[0].spec.containers[0].image}'
kubectl get pods -n genesis
The StatefulSet will perform a rolling update, and the persistent volume will be reattached to the new pod.

Uninstalling

# Uninstall Helm release
helm uninstall genesis

# Note: PVC is retained by default to preserve data
# To delete PVC and all data:
kubectl delete pvc genesis-data-genesis-0 -n genesis

# Delete namespace
kubectl delete namespace genesis
Deleting the PVC will permanently remove all Genesis data including the database, git repositories, and uploaded files.

Additional Resources