Deployment
Deploy Lasius to Kubernetes environments.
This guide covers deploying Lasius to a Kubernetes cluster.
Prerequisites
- Kubernetes cluster (1.25+)
- kubectl configured
- Helm 3.x installed
- PostgreSQL database
- Redis instance
- Container registry access
Architecture Overview
┌─────────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Ingress │ │ Ingress │ │
│ │ (Frontend) │ │ (API) │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Frontend │ │ Backend │ │ Knowledge Base │ │
│ │ Deployment │ │ Deployment │ │ Deployment │ │
│ │ (3 pods) │ │ (3 pods) │ │ (2 pods) │ │
│ └─────────────┘ └──────┬──────┘ └─────────────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Temporal │ │ MCP │ │ Worker │ │
│ │ Server │ │ Gateway │ │ Pods │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Persistent Storage │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ PostgreSQL│ │ Redis │ │ S3 │ │ │
│ │ │ (PVC) │ │ (PVC) │ │ (External)│ │ │
│ │ └───────────┘ └───────────┘ └───────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Step 1: Create Namespace
kubectl create namespace lasius
kubectl config set-context --current --namespace=lasius
Step 2: Configure Secrets
Create secrets for database and API credentials:
# secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: lasius-secrets
namespace: lasius
type: Opaque
stringData:
POSTGRES_USER: "lasius"
POSTGRES_PASSWORD: "<your-password>"
POSTGRES_HOST: "postgres.lasius.svc.cluster.local"
POSTGRES_DB: "lasius"
REDIS_HOST: "redis.lasius.svc.cluster.local"
REDIS_PASSWORD: "<redis-password>"
JWT_SECRET: "<jwt-secret>"
ENCRYPTION_SECRET: "<encryption-key>"
kubectl apply -f secrets.yaml
Step 3: Deploy PostgreSQL
# postgres.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: lasius
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: pgvector/pgvector:pg16
ports:
- containerPort: 5432
envFrom:
- secretRef:
name: lasius-secrets
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: lasius
spec:
ports:
- port: 5432
selector:
app: postgres
Step 4: Deploy Redis
# redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: lasius
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
args: ["--requirepass", "$(REDIS_PASSWORD)"]
envFrom:
- secretRef:
name: lasius-secrets
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: lasius
spec:
ports:
- port: 6379
selector:
app: redis
Step 5: Deploy Temporal
# temporal.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: temporal
namespace: lasius
spec:
replicas: 1
selector:
matchLabels:
app: temporal
template:
metadata:
labels:
app: temporal
spec:
containers:
- name: temporal
image: temporalio/auto-setup:latest
ports:
- containerPort: 7233
env:
- name: DB
value: "postgresql"
- name: DB_PORT
value: "5432"
- name: POSTGRES_SEEDS
value: "postgres.lasius.svc.cluster.local"
envFrom:
- secretRef:
name: lasius-secrets
---
apiVersion: v1
kind: Service
metadata:
name: temporal
namespace: lasius
spec:
ports:
- port: 7233
selector:
app: temporal
Step 6: Deploy Backend
# backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lasius-backend
namespace: lasius
spec:
replicas: 3
selector:
matchLabels:
app: lasius-backend
template:
metadata:
labels:
app: lasius-backend
spec:
containers:
- name: backend
image: <registry>/lasius-backend:latest
ports:
- containerPort: 8000
envFrom:
- secretRef:
name: lasius-secrets
env:
- name: TEMPORAL_HOST
value: "temporal.lasius.svc.cluster.local:7233"
- name: KB_SERVICE_URL
value: "http://lasius-kb.lasius.svc.cluster.local:8001"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: lasius-backend
namespace: lasius
spec:
ports:
- port: 8000
selector:
app: lasius-backend
Step 7: Deploy Knowledge Base
# knowledge-base.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lasius-kb
namespace: lasius
spec:
replicas: 2
selector:
matchLabels:
app: lasius-kb
template:
metadata:
labels:
app: lasius-kb
spec:
containers:
- name: kb
image: <registry>/lasius-knowledge-base:latest
ports:
- containerPort: 8001
envFrom:
- secretRef:
name: lasius-secrets
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
---
apiVersion: v1
kind: Service
metadata:
name: lasius-kb
namespace: lasius
spec:
ports:
- port: 8001
selector:
app: lasius-kb
Step 8: Deploy MCP Gateway
# mcp-gateway.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lasius-mcp-gateway
namespace: lasius
spec:
replicas: 2
selector:
matchLabels:
app: lasius-mcp-gateway
template:
metadata:
labels:
app: lasius-mcp-gateway
spec:
containers:
- name: mcp-gateway
image: <registry>/lasius-mcp-gateway:latest
ports:
- containerPort: 3000
envFrom:
- secretRef:
name: lasius-secrets
env:
- name: DATABASE_URL
value: "postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):5432/lasius_mcp"
---
apiVersion: v1
kind: Service
metadata:
name: lasius-mcp-gateway
namespace: lasius
spec:
ports:
- port: 3000
selector:
app: lasius-mcp-gateway
Step 9: Deploy Frontend
# frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lasius-frontend
namespace: lasius
spec:
replicas: 3
selector:
matchLabels:
app: lasius-frontend
template:
metadata:
labels:
app: lasius-frontend
spec:
containers:
- name: frontend
image: <registry>/lasius-frontend:latest
ports:
- containerPort: 3000
env:
- name: NEXT_PUBLIC_API_URL
value: "https://api.lasius.io"
- name: NEXT_PUBLIC_WS_URL
value: "wss://api.lasius.io"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: lasius-frontend
namespace: lasius
spec:
ports:
- port: 3000
selector:
app: lasius-frontend
Step 10: Configure Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lasius-ingress
namespace: lasius
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- lasius.io
- api.lasius.io
secretName: lasius-tls
rules:
- host: lasius.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lasius-frontend
port:
number: 3000
- host: api.lasius.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lasius-backend
port:
number: 8000
Step 11: Deploy Temporal Worker
# temporal-worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lasius-worker
namespace: lasius
spec:
replicas: 3
selector:
matchLabels:
app: lasius-worker
template:
metadata:
labels:
app: lasius-worker
spec:
containers:
- name: worker
image: <registry>/lasius-backend:latest
command: ["python", "-m", "app.temporal.worker"]
envFrom:
- secretRef:
name: lasius-secrets
env:
- name: TEMPORAL_HOST
value: "temporal.lasius.svc.cluster.local:7233"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
Apply All Resources
kubectl apply -f secrets.yaml
kubectl apply -f postgres.yaml
kubectl apply -f redis.yaml
kubectl apply -f temporal.yaml
kubectl apply -f backend.yaml
kubectl apply -f knowledge-base.yaml
kubectl apply -f mcp-gateway.yaml
kubectl apply -f frontend.yaml
kubectl apply -f temporal-worker.yaml
kubectl apply -f ingress.yaml
Verify Deployment
# Check all pods are running
kubectl get pods -n lasius
# Check services
kubectl get svc -n lasius
# Check ingress
kubectl get ingress -n lasius
# View logs
kubectl logs -f deployment/lasius-backend -n lasius
Environment Variables Reference
| Variable | Service | Description |
|---|---|---|
POSTGRES_HOST | All | PostgreSQL hostname |
POSTGRES_USER | All | Database username |
POSTGRES_PASSWORD | All | Database password |
REDIS_HOST | Backend | Redis hostname |
TEMPORAL_HOST | Backend, Worker | Temporal server address |
KB_SERVICE_URL | Backend | Knowledge Base service URL |
JWT_SECRET | Backend, Gateway | JWT signing secret |
ENCRYPTION_SECRET | Gateway | Encryption key |
Scaling
# Scale backend pods
kubectl scale deployment lasius-backend --replicas=5 -n lasius
# Scale workers based on workflow load
kubectl scale deployment lasius-worker --replicas=10 -n lasius
# Enable HPA (Horizontal Pod Autoscaler)
kubectl autoscale deployment lasius-backend \
--min=3 --max=10 --cpu-percent=70 -n lasius
Monitoring
Deploy monitoring stack:
# Install Prometheus & Grafana via Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack -n lasius
See Also: Architecture