Kubernetes
Deploy Colanode on Kubernetes for production environments requiring high availability, scalability, and professional operations. This guide uses Helm charts to simplify deployment and management.
Architecture Overview
The Helm chart deploys a complete Colanode stack:
- Colanode Server: Main application server (scalable)
- PostgreSQL: Database with pgvector extension
- Redis/Valkey: Message queue and caching
- MinIO: S3-compatible object storage
- Ingress: HTTPS termination and routing (optional)
Quick Installation
- Add the Helm Repository
# Add the official Colanode Helm repository
helm repo add colanode https://static.colanode.com/hosting/kubernetes/chart
# Update repository
helm repo update
# Search for available charts
helm search repo colanode
- Install with Default Values
# Install Colanode with default configuration
helm install my-colanode colanode/colanode
# Monitor deployment
kubectl get pods -w
- Access Your Deployment
# Get service information
kubectl get services
# Port forward for local access (temporary)
kubectl port-forward svc/my-colanode 3000:3000
# Access via browser: http://localhost:3000
Custom Installation
- Create
values.yamlwith your customizations:
# values.yaml
colanode:
replicaCount: 2
image:
repository: ghcr.io/colanode/server
tag: "latest"
pullPolicy: IfNotPresent
# Enable config file override
configFile:
enabled: true
# We will pass the content via --set-file or you can inline it here if it's small
# data: |
# { ... }
ingress:
enabled: true
className: "nginx"
hosts:
- host: colanode.company.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: colanode-tls
hosts:
- colanode.company.com
# Dependencies
postgresql:
enabled: true
auth:
username: colanode_user
password: secure_postgres_password
database: colanode_db
primary:
persistence:
size: 20Gi
redis:
enabled: true
auth:
password: secure_redis_password
master:
persistence:
size: 8Gi
minio:
enabled: true
auth:
rootUser: admin
rootPassword: secure_minio_password
persistence:
size: 50Gi
- Install with Custom Values and Config File
# Install with custom configuration and config.json
helm install my-colanode colanode/colanode -f values.yaml \
--set-file colanode.configFile.data=./config.json
# Upgrade existing installation
helm upgrade my-colanode colanode/colanode -f values.yaml \
--set-file colanode.configFile.data=./config.json
Configuration model
-
The Colanode server image already contains a full
config.json, so the chart works out of the box without extra values. Only secrets referenced viaenv://(for examplePOSTGRES_URL,REDIS_URL) must remain in environment variables. -
To supply your own configuration file, enable the helper values:
colanode: configFile: enabled: true # Recommended: pass the file at install time instead of inliningThen install with:
helm install my-colanode ./hosting/kubernetes/chart \ --set colanode.configFile.enabled=true \ --set-file colanode.configFile.data=./config.json -
If you already manage a ConfigMap, set
colanode.configFile.existingConfigMap=<name>and the chart will mount it at/app/apps/server/config.json. -
Keep secrets as environment variables referenced from JSON via
env://SECRET_NAME.
Environment variables do not override JSON values unless explicitly referenced.
Configuration Options
Core Colanode Settings
| Parameter | Description | Default |
|---|---|---|
colanode.replicaCount | Number of Colanode server replicas | 1 |
colanode.image.repository | Colanode server image repository | ghcr.io/colanode/server |
colanode.image.tag | Image tag | latest |
colanode.nodeEnv | Node environment (NODE_ENV) | production |
colanode.additionalEnv | Extra env vars (for secrets) | [] |
Resource Configuration
colanode:
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
nodeSelector:
kubernetes.io/os: linux
tolerations: []
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- colanode
topologyKey: kubernetes.io/hostname
Ingress Configuration
colanode:
ingress:
enabled: true
className: "nginx" # or "traefik", "alb", etc.
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
hosts:
- host: colanode.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: colanode-tls
hosts:
- colanode.example.com
Database Configuration
The chart uses a custom PostgreSQL image with pgvector extension:
postgresql:
enabled: true
image:
repository: pgvector/pgvector
tag: "pg17"
auth:
username: colanode_user
password: your_secure_password
database: colanode_db
primary:
persistence:
enabled: true
size: 50Gi
storageClass: "fast-ssd"
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
configuration: |
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
wal_buffers = 16MB
To use an external PostgreSQL database:
postgresql:
enabled: false
colanode:
# Pass connection string via env var (referenced by default config.json)
additionalEnv:
- name: POSTGRES_URL
value: "postgres://user:password@external-db:5432/colanode_db"
Storage Configuration
The Helm chart supports four storage backends: File System, S3, Google Cloud Storage, and Azure Blob Storage. Configure using the colanode.storage values.
File System Storage
Uses Kubernetes Persistent Volume Claims to store files.
Basic Configuration:
colanode:
storage:
type: file
file:
directory: /var/lib/colanode/storage
persistence:
enabled: true
size: 20Gi
storageClass: "" # Use cluster default
accessModes:
- ReadWriteOnce
Using an Existing PVC:
colanode:
storage:
type: file
file:
directory: /var/lib/colanode/storage
persistence:
enabled: true
existingClaim: "my-existing-pvc"
Using emptyDir (ephemeral):
colanode:
storage:
type: file
file:
directory: /var/lib/colanode/storage
persistence:
enabled: false
S3-Compatible Storage
Option 1: Using Bundled MinIO (Default)
Enable MinIO in the Helm chart:
minio:
enabled: true
persistence:
enabled: true
size: 100Gi
storageClass: "fast-ssd"
colanode:
storage:
type: s3
s3:
bucket: colanode
region: us-east-1
# endpoint, accessKey, and secretKey auto-configured from MinIO
Option 2: Using External S3
Disable MinIO and configure external S3:
minio:
enabled: false
colanode:
storage:
type: s3
s3:
endpoint: "https://s3.amazonaws.com"
bucket: my-colanode-bucket
region: us-west-2
forcePathStyle: false
accessKey:
value: "AKIA..."
secretKey:
value: "..."
Option 3: Using Existing Secrets
Reference existing Kubernetes secrets:
colanode:
storage:
type: s3
s3:
endpoint: "https://s3.amazonaws.com"
bucket: my-bucket
region: us-west-2
accessKey:
existingSecret: "aws-credentials"
secretKey: "access-key-id"
secretKey:
existingSecret: "aws-credentials"
secretKey: "secret-access-key"
Google Cloud Storage
Configure GCS with a service account secret:
Step 1: Create a Kubernetes secret with your GCP service account key:
kubectl create secret generic gcs-credentials \
--from-file=key.json=/path/to/service-account.json
Step 2: Configure Helm values:
colanode:
storage:
type: gcs
gcs:
bucket: my-colanode-bucket
projectId: my-gcp-project-123
credentialsSecret:
name: gcs-credentials
key: key.json
mountPath: /var/secrets/gcp
fileName: service-account.json
Alternative: Use a credentials path (if managing the file separately):
colanode:
storage:
type: gcs
gcs:
bucket: my-colanode-bucket
projectId: my-gcp-project-123
credentialsPath: /etc/gcp/credentials.json
Azure Blob Storage
Configure Azure storage with account credentials:
Basic Configuration:
colanode:
storage:
type: azure
azure:
account: mystorageaccount
containerName: colanode
accountKey:
value: "base64encodedkey=="
Using an Existing Secret:
colanode:
storage:
type: azure
azure:
account: mystorageaccount
containerName: colanode
accountKey:
existingSecret: "azure-storage-credentials"
secretKey: "account-key"
High Availability Setup
Multi-Replica Deployment
colanode:
replicaCount: 3
podDisruptionBudget:
enabled: true
minAvailable: 2
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
postgresql:
architecture: replication
readReplicas:
replicaCount: 2
redis:
architecture: replication
replica:
replicaCount: 2
minio:
mode: distributed
statefulset:
replicaCount: 4
Load Balancing
colanode:
service:
type: ClusterIP
port: 3000
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
ingress:
annotations:
nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
nginx.ingress.kubernetes.io/session-cookie-name: "colanode-affinity"
nginx.ingress.kubernetes.io/session-cookie-expires: "86400"
Monitoring and Observability
Prometheus Metrics
colanode:
metrics:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
interval: 30s
path: /metrics
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3000"
prometheus.io/path: "/metrics"
Logging Configuration
colanode:
logging:
level: "info"
format: "json"
podAnnotations:
fluentbit.io/parser: "json"
Security Configuration
Network Policies
networkPolicies:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 3000
Pod Security Standards
colanode:
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
Secrets Management
colanode:
# existingSecret: "colanode-secrets" # Not used by default chart logic anymore, use additionalEnv or specific secret keys
# Example of injecting secrets via additionalEnv
additionalEnv:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: colanode-secrets
key: postgres-password
Create the secret:
kubectl create secret generic colanode-secrets \
--from-literal=postgres-password=your_postgres_password \
--from-literal=redis-password=your_redis_password \
--from-literal=minio-password=your_minio_password
Example: Configuring Cloudflare R2 as ‘s3’ storage
Here is a complete example of configuring Cloudflare R2 storage using additionalEnv to inject secrets into a custom configuration.
1. Prepare custom config (config.json) with env:// references:
{
"storage": {
"provider": {
"type": "s3",
"endpoint": "env://R2_ENDPOINT",
"accessKey": "env://R2_ACCESS_KEY",
"secretKey": "env://R2_SECRET_KEY",
"bucket": "env://R2_BUCKET",
"region": "auto"
}
}
}
2. Create the secret:
kubectl create secret generic r2-creds \
--from-literal=access-key="YOUR_R2_ACCESS_KEY_ID" \
--from-literal=secret-key="YOUR_R2_SECRET_ACCESS_KEY"
3. Configure values (r2-values.yaml) to map the secret:
colanode:
configFile:
enabled: true
additionalEnv:
- name: R2_ENDPOINT
value: "https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
- name: R2_BUCKET
value: "my-bucket-name"
- name: R2_ACCESS_KEY
valueFrom:
secretKeyRef:
name: r2-creds
key: access-key
- name: R2_SECRET_KEY
valueFrom:
secretKeyRef:
name: r2-creds
key: secret-key
4. Deploy:
helm upgrade --install my-colanode colanode/colanode \
-f r2-values.yaml \
--set-file colanode.configFile.data=custom-config.json
Management Commands
Installation Management
# List Helm releases
helm list
# Get release status
helm status my-colanode
# View release history
helm history my-colanode
# Rollback to previous version
helm rollback my-colanode 1
Scaling Operations
# Scale Colanode replicas
kubectl scale deployment my-colanode --replicas=5
# Scale via Helm
helm upgrade my-colanode colanode/colanode --set colanode.replicaCount=5
Monitoring and Debugging
# Check pod status
kubectl get pods -l app.kubernetes.io/name=colanode
# View pod logs
kubectl logs -f deployment/my-colanode
# Execute into pod
kubectl exec -it deployment/my-colanode -- /bin/sh
# Port forward for debugging
kubectl port-forward svc/my-colanode 3000:3000
Backup and Recovery
Database Backup
# Add to values.yaml
postgresql:
backup:
enabled: true
schedule: "0 2 * * *" # Daily at 2 AM
storage:
size: 20Gi
storageClass: "standard"
Manual backup:
# Create database backup
kubectl exec -it my-colanode-postgresql-0 -- pg_dump -U colanode_user colanode_db > backup.sql
# Restore from backup
kubectl exec -i my-colanode-postgresql-0 -- psql -U colanode_user colanode_db < backup.sql
MinIO Backup
# Backup MinIO data
kubectl exec -it my-colanode-minio-0 -- mc mirror local/colanode-files /backup/files/
# Restore MinIO data
kubectl exec -it my-colanode-minio-0 -- mc mirror /backup/files/ local/colanode-files
Upgrading
Upgrade Process
# Update Helm repository
helm repo update
# Check available versions
helm search repo colanode -l
# Upgrade to latest version
helm upgrade my-colanode colanode/colanode
# Upgrade to specific version
helm upgrade my-colanode colanode/colanode --version 1.2.3
Rolling Updates
colanode:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1