Skip to main content
This guide walks you through deploying the Genesis container to an existing Azure AKS (Azure 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

Azure AKS Cluster Requirements

AKS Cluster

Kubernetes version 1.23 or higher

kubectl

Configured to access your AKS cluster

Helm 3.8+

For deploying the Genesis Helm chart

Azure CLI

Configured with appropriate credentials
Verify cluster access:
az aks get-credentials --resource-group <resource-group> --name <cluster-name>
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, Azure OpenAI, etc.) if using those LLM providers

Azure Permissions

The AKS cluster’s managed identity or service principal needs appropriate permissions for:
  • Azure Disk operations (for persistent volumes)
  • Azure Container Registry access (if using ACR)
  • Azure Key Vault access (if storing secrets in Key Vault)

Azure Disk CSI Driver Setup

Genesis requires persistent storage for its database, git repositories, and uploaded files. The Azure Disk CSI driver must be installed in your cluster to provision Azure managed disks.
The Azure Disk CSI driver is automatically installed by default on AKS clusters. However, verify it’s running and properly configured.
Check if installed:
kubectl get pods -n kube-system | grep csi-azuredisk

Installation Instructions

If not installed, refer to the Azure Kubernetes Service documentation for detailed Azure Disk CSI driver installation steps.

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 managed-csi or managed-premium on AKS)

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: "openai"  # Optional
OPENAI_API_KEY: "<your-api-key>"
BOT_OS_DEFAULT_LLM_ENGINE: "openai"  # Optional
OPENAI_API_KEY: "<azure-openai-api-key>"
AZURE_OPENAI_API_ENDPOINT: "https://<resource-name>.openai.azure.com/"
AZURE_OPENAI_API_VERSION: "2024-12-01-preview"
AZURE_OPENAI_DEPLOYMENT: "<deployment-name>"
OPENAI_MODEL_NAME: "<model-name>"  # e.g., "gpt-4" or "gpt-35-turbo"
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 AKS 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 or Azure OpenAI

# Non-sensitive configuration
config:
  sqliteDbPath: "/app/.genesis/db/genesis.db"
  logLevel: "INFO"
  logsFormat: "json"
  authEnabled: "true"
  authProvider: "proxy"  # For ingress-based authentication
  
  # Azure OpenAI configuration (if using Azure OpenAI)
  extraEnv:
    BOT_OS_DEFAULT_LLM_ENGINE: "openai"  # Optional: helps with initial setup
    AZURE_OPENAI_API_ENDPOINT: "https://<resource-name>.openai.azure.com/"
    AZURE_OPENAI_API_VERSION: "2024-12-01-preview"
    AZURE_OPENAI_DEPLOYMENT: "<deployment-name>"
    OPENAI_MODEL_NAME: "gpt-4"  # or "gpt-35-turbo"

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

# Persistent storage
persistence:
  storageClassName: ""  # Uses cluster default (managed-csi or managed-premium)
  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: "azure/application-gateway"  # For Application Gateway, or "nginx" for NGINX
  
  # For Application Gateway Ingress Controller
  annotations:
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
    appgw.ingress.kubernetes.io/health-probe-path: "/api/health"
    appgw.ingress.kubernetes.io/health-probe-interval: "30"
    appgw.ingress.kubernetes.io/health-probe-timeout: "10"
    appgw.ingress.kubernetes.io/health-probe-unhealthy-threshold: "3"
    # For HTTPS, configure certificate in Application Gateway
    # appgw.ingress.kubernetes.io/appgw-ssl-certificate: "<certificate-name>"
  
  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 managed-csi or managed-premium)
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.

Azure-Specific Considerations

Managed Identity for Azure OpenAI

If using Azure OpenAI, you can configure a managed identity to access Azure OpenAI without storing API keys in Kubernetes secrets:
1

Create Managed Identity

If not using cluster’s managed identity:
az identity create --resource-group <resource-group> --name genesis-identity
2

Grant Permissions

# Get the identity's principal ID
PRINCIPAL_ID=$(az identity show --resource-group <resource-group> --name genesis-identity --query principalId -o tsv)

# Grant "Cognitive Services User" role on Azure OpenAI resource
az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Cognitive Services User" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<azure-openai-resource-name>
3

Configure Pod Identity

For Workload Identity:
  • Create a service account with the managed identity annotation
  • Configure the StatefulSet to use the service account
4

Retrieve API Key (Optional)

Using managed identity in an init container or startup script:
az login --identity
az cognitiveservices account keys list \
  --name <azure-openai-resource-name> \
  --resource-group <resource-group> \
  --query key1 -o tsv

Azure Disk Encryption

Azure managed disks created by the Azure Disk CSI driver on AKS are encrypted by default. Verify:
kubectl get storageclass -o yaml

Virtual Network Configuration

Ensure your AKS cluster nodes have:
RequirementPurpose
Outbound Internet AccessFor pulling images from the container registry provided by Genesis
DNS ResolutionFor external API calls (OpenAI, Azure OpenAI, etc.)
Network Security Group RulesAllow ingress on ports 80/443 if using Application Gateway, 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 Azure Disk 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 Azure Disk CSI driver logs
kubectl logs -n kube-system -l app=csi-azuredisk-controller
For Application Gateway Ingress Controller:
# Check controller logs
kubectl logs -n kube-system -l app=ingress-azure

# Check ingress status
kubectl describe ingress -n genesis genesis

# Verify Application Gateway configuration
az network application-gateway show \
  --resource-group <resource-group> \
  --name <application-gateway-name>
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