Files
chatwoot/developer-docs/self-hosted/deployment/kubernetes.mdx
T

537 lines
10 KiB
Plaintext

---
title: Kubernetes Deployment
description: Deploy Chatwoot on Kubernetes using Helm charts for scalable, production-ready installations
sidebarTitle: Kubernetes
---
# Kubernetes Deployment Guide
Deploy Chatwoot on Kubernetes using our official Helm charts for a scalable, production-ready installation.
## Prerequisites
Before deploying Chatwoot on Kubernetes, ensure you have:
- **Kubernetes cluster** (v1.19+) with sufficient resources
- **Helm 3.x** installed and configured
- **kubectl** configured to access your cluster
- **Ingress controller** (nginx, traefik, etc.) for external access
- **Cert-manager** (optional, for automatic SSL certificates)
### Minimum Resource Requirements
- **CPU**: 2 cores minimum (4+ cores recommended)
- **Memory**: 4GB RAM minimum (8GB+ recommended)
- **Storage**: 20GB persistent storage for PostgreSQL
- **Nodes**: 3+ nodes for high availability
## Quick Start
### 1. Add Chatwoot Helm Repository
```bash
helm repo add chatwoot https://chatwoot.github.io/charts
helm repo update
```
### 2. Create Namespace
```bash
kubectl create namespace chatwoot
```
### 3. Install with Default Values
```bash
helm install chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--set ingress.enabled=true \
--set ingress.hosts[0].host=chatwoot.yourdomain.com \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix
```
## Production Configuration
### Custom Values File
Create a `values.yaml` file for production deployment:
```yaml
# values.yaml
replicaCount: 3
image:
repository: chatwoot/chatwoot
tag: "latest"
pullPolicy: IfNotPresent
env:
RAILS_ENV: production
NODE_ENV: production
FRONTEND_URL: "https://chatwoot.yourdomain.com"
FORCE_SSL: "true"
# Database Configuration
postgresql:
enabled: true
auth:
postgresPassword: "your-secure-password"
database: "chatwoot_production"
primary:
persistence:
enabled: true
size: 50Gi
storageClass: "fast-ssd"
metrics:
enabled: true
# Redis Configuration
redis:
enabled: true
auth:
enabled: true
password: "your-redis-password"
master:
persistence:
enabled: true
size: 10Gi
metrics:
enabled: true
# Ingress Configuration
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
hosts:
- host: chatwoot.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: chatwoot-tls
hosts:
- chatwoot.yourdomain.com
# Resource Limits
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
# Horizontal Pod Autoscaler
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
# Storage Configuration
persistence:
enabled: true
storageClass: "fast-ssd"
size: 20Gi
# Service Configuration
service:
type: ClusterIP
port: 3000
# Worker Configuration
worker:
enabled: true
replicaCount: 2
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# Monitoring
serviceMonitor:
enabled: true
namespace: monitoring
```
### Deploy with Custom Configuration
```bash
helm install chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml
```
## External Dependencies
### Using External PostgreSQL
```yaml
postgresql:
enabled: false
env:
DATABASE_URL: "postgresql://username:password@postgres-host:5432/chatwoot_production"
```
### Using External Redis
```yaml
redis:
enabled: false
env:
REDIS_URL: "redis://redis-host:6379/0"
```
### Using Cloud Storage
```yaml
env:
# AWS S3
ACTIVE_STORAGE_SERVICE: "amazon"
S3_BUCKET_NAME: "your-chatwoot-bucket"
AWS_ACCESS_KEY_ID: "your-access-key"
AWS_SECRET_ACCESS_KEY: "your-secret-key"
AWS_REGION: "us-east-1"
# Google Cloud Storage
# ACTIVE_STORAGE_SERVICE: "google"
# GCS_PROJECT: "your-project"
# GCS_BUCKET: "your-bucket"
```
## High Availability Setup
### Multi-Zone Deployment
```yaml
# Spread pods across availability zones
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- chatwoot
topologyKey: topology.kubernetes.io/zone
# Node selection
nodeSelector:
node-type: "application"
# Tolerations for dedicated nodes
tolerations:
- key: "dedicated"
operator: "Equal"
value: "chatwoot"
effect: "NoSchedule"
```
### Database High Availability
```yaml
postgresql:
enabled: true
architecture: replication
auth:
replicationPassword: "replication-password"
primary:
persistence:
enabled: true
size: 100Gi
readReplicas:
replicaCount: 2
persistence:
enabled: true
size: 100Gi
```
## Security Configuration
### Network Policies
```yaml
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: chatwoot-network-policy
namespace: chatwoot
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: chatwoot
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 3000
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: postgresql
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: redis
ports:
- protocol: TCP
port: 6379
```
### Pod Security Standards
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
```
## Monitoring and Observability
### Prometheus Monitoring
```yaml
serviceMonitor:
enabled: true
labels:
app: chatwoot
interval: 30s
scrapeTimeout: 10s
path: /metrics
# Custom metrics
env:
PROMETHEUS_EXPORTER: "true"
PROMETHEUS_EXPORTER_PORT: "9394"
```
### Logging Configuration
```yaml
# Structured logging
env:
LOG_LEVEL: "info"
LOG_FORMAT: "json"
# Log aggregation with Fluentd/Fluent Bit
annotations:
fluentbit.io/parser: "json"
fluentbit.io/exclude: "false"
```
### Health Checks
```yaml
livenessProbe:
httpGet:
path: /api
port: 3000
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /api
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
```
## Backup and Disaster Recovery
### Database Backup
```yaml
# CronJob for database backup
apiVersion: batch/v1
kind: CronJob
metadata:
name: chatwoot-db-backup
namespace: chatwoot
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: postgres-backup
image: postgres:15
command:
- /bin/bash
- -c
- |
pg_dump $DATABASE_URL | gzip > /backup/chatwoot-$(date +%Y%m%d-%H%M%S).sql.gz
# Upload to S3 or other storage
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: chatwoot-secrets
key: database-url
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvc
restartPolicy: OnFailure
```
## Upgrading Chatwoot
### Rolling Update
```bash
# Update to latest version
helm upgrade chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml
# Update to specific version
helm upgrade chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml \
--set image.tag="v2.15.0"
```
### Database Migration
```bash
# Run migrations after upgrade
kubectl exec -it deployment/chatwoot -n chatwoot -- \
bundle exec rails db:migrate RAILS_ENV=production
```
## Troubleshooting
### Common Issues
<Tip>
**Pod Startup Issues**: Check resource limits and node capacity
```bash
kubectl describe pod <pod-name> -n chatwoot
kubectl top nodes
```
</Tip>
<Warning>
**Database Connection Issues**: Verify database credentials and network policies
```bash
kubectl logs deployment/chatwoot -n chatwoot
kubectl exec -it deployment/chatwoot -n chatwoot -- nc -zv postgres-host 5432
```
</Warning>
### Debug Commands
```bash
# Check pod status
kubectl get pods -n chatwoot
# View logs
kubectl logs -f deployment/chatwoot -n chatwoot
# Access pod shell
kubectl exec -it deployment/chatwoot -n chatwoot -- /bin/bash
# Check service endpoints
kubectl get endpoints -n chatwoot
# Describe ingress
kubectl describe ingress chatwoot -n chatwoot
```
### Performance Tuning
```yaml
# Optimize for high traffic
env:
RAILS_MAX_THREADS: "20"
WEB_CONCURRENCY: "4"
SIDEKIQ_CONCURRENCY: "25"
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 2000m
memory: 4Gi
# Database connection pooling
env:
DATABASE_POOL_SIZE: "25"
```
## Best Practices
### Resource Management
- Set appropriate resource requests and limits
- Use horizontal pod autoscaling for dynamic scaling
- Monitor resource usage and adjust as needed
### Security
- Use network policies to restrict traffic
- Enable pod security standards
- Regularly update container images
- Use secrets for sensitive configuration
### Monitoring
- Enable Prometheus metrics collection
- Set up alerting for critical metrics
- Monitor application and infrastructure health
- Use distributed tracing for complex issues
### Backup
- Implement automated database backups
- Test backup restoration procedures
- Store backups in multiple locations
- Document recovery procedures
---
This Kubernetes deployment guide provides a solid foundation for running Chatwoot in production. Customize the configuration based on your specific requirements and infrastructure setup.