537 lines
10 KiB
Plaintext
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. |