Real-world deployment patterns and configuration examples for Frappe Operator.
Note: All example YAML files are available in the
examples/directory of the repository.
The fastest way to get started is using the minimal example:
kubectl apply -f https://raw.githubusercontent.com/vyogotech/frappe-operator/main/examples/minimal-bench-and-site.yaml
Or clone the repository:
git clone https://github.com/vyogotech/frappe-operator.git
cd frappe-operator/examples
kubectl apply -f minimal-bench-and-site.yaml
Perfect for local development and testing.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: dev-bench
namespace: default
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext"]'
domainConfig:
suffix: ".local"
autoDetect: false
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: mysite
namespace: default
spec:
benchRef:
name: dev-bench
siteName: "mysite"
dbConfig:
mode: shared
ingress:
enabled: true
className: "nginx"
Access:
kubectl port-forward service/dev-bench-nginx 8080:8080
# Add to /etc/hosts: 127.0.0.1 mysite.local
# Access: http://mysite.local:8080
Production-ready configuration with proper resources and TLS.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: prod-bench
namespace: production
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms"]'
imageConfig:
repository: frappe/erpnext
tag: v15.0.0
pullPolicy: IfNotPresent
componentReplicas:
gunicorn: 3
socketio: 2
workerDefault: 2
workerLong: 2
workerShort: 1
componentResources:
gunicorn:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
socketio:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
scheduler:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
workerDefault:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"
workerLong:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"
workerShort:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
redisConfig:
type: dragonfly
maxMemory: "4gb"
resources:
requests:
cpu: "500m"
memory: "4Gi"
limits:
cpu: "1"
memory: "6Gi"
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: erp-site
namespace: production
spec:
benchRef:
name: prod-bench
siteName: "erp.example.com"
domain: "erp.example.com"
adminPasswordSecretRef:
name: erp-admin-password
dbConfig:
mode: dedicated
storageSize: "100Gi"
resources:
requests:
cpu: "1"
memory: "4Gi"
limits:
cpu: "2"
memory: "8Gi"
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
---
# Admin password secret
apiVersion: v1
kind: Secret
metadata:
name: erp-admin-password
namespace: production
type: Opaque
stringData:
password: "YourSecurePassword123!"
One bench serving multiple customer sites - cost-effective SaaS model.
---
# Shared bench for all customers
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: saas-bench
namespace: saas-platform
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms"]'
# Automatic domain assignment
domainConfig:
suffix: ".myplatform.com"
componentReplicas:
gunicorn: 5
socketio: 3
workerDefault: 5
workerLong: 3
workerShort: 2
componentResources:
gunicorn:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
workerDefault:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
redisConfig:
type: dragonfly
maxMemory: "8gb"
---
# Customer 1 - Shared database
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: customer1
namespace: saas-platform
spec:
benchRef:
name: saas-bench
siteName: "customer1" # Results in: customer1.myplatform.com
dbConfig:
mode: shared
mariadbRef:
name: shared-mariadb
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
---
# Customer 2 - Shared database
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: customer2
namespace: saas-platform
spec:
benchRef:
name: saas-bench
siteName: "customer2" # Results in: customer2.myplatform.com
dbConfig:
mode: shared
mariadbRef:
name: shared-mariadb
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
---
# Customer 3 - Dedicated database (enterprise tier)
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: enterprise-customer
namespace: saas-platform
spec:
benchRef:
name: saas-bench
siteName: "enterprise-customer"
dbConfig:
mode: dedicated
storageSize: "200Gi"
resources:
requests: { cpu: "2", memory: "8Gi" }
limits: { cpu: "4", memory: "16Gi" }
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
Complete isolation with dedicated resources.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: acme-corp-bench
namespace: acme-corp
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms", "custom_app"]'
imageConfig:
repository: acmecorp.azurecr.io/frappe-custom
tag: v15-acme-1.0.0
pullPolicy: Always
pullSecrets:
- name: acr-credentials
componentReplicas:
gunicorn: 10
socketio: 5
workerDefault: 10
workerLong: 5
workerShort: 3
componentResources:
gunicorn:
requests: { cpu: "2", memory: "4Gi" }
limits: { cpu: "4", memory: "8Gi" }
workerDefault:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
redisConfig:
type: dragonfly
maxMemory: "16gb"
storageSize: "50Gi"
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: acme-erp
namespace: acme-corp
spec:
benchRef:
name: acme-corp-bench
siteName: "erp.acme.com"
domain: "erp.acme.com"
dbConfig:
mode: external # Using Azure Database for MySQL
connectionSecretRef:
name: azure-mysql-credentials
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "500m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
nginx.ingress.kubernetes.io/rate-limit: "100"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
---
# External database credentials
apiVersion: v1
kind: Secret
metadata:
name: azure-mysql-credentials
namespace: acme-corp
type: Opaque
stringData:
host: "acme-mysql.mysql.database.azure.com"
port: "3306"
database: "acme_erp"
username: "acme_admin@acme-mysql"
password: "YourAzureMySQLPassword"
Each site with its own custom domain.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: multi-domain-bench
namespace: default
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext"]'
---
# Site 1: Custom domain
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: site-company-a
namespace: default
spec:
benchRef:
name: multi-domain-bench
siteName: "erp.company-a.com"
domain: "erp.company-a.com"
dbConfig:
mode: dedicated
storageSize: "50Gi"
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
---
# Site 2: Different custom domain
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: site-company-b
namespace: default
spec:
benchRef:
name: multi-domain-bench
siteName: "system.company-b.net"
domain: "system.company-b.net"
dbConfig:
mode: dedicated
storageSize: "50Gi"
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
certManagerIssuer: "letsencrypt-prod"
High-availability configuration with horizontal pod autoscaling.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: ha-bench
namespace: production
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms"]'
# Start with moderate replicas
componentReplicas:
gunicorn: 5
socketio: 3
workerDefault: 3
workerLong: 2
workerShort: 2
componentResources:
gunicorn:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
socketio:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
workerDefault:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
redisConfig:
type: dragonfly
maxMemory: "8gb"
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: ha-site
namespace: production
spec:
benchRef:
name: ha-bench
siteName: "erp.example.com"
dbConfig:
mode: external
connectionSecretRef:
name: rds-mariadb-galera # AWS RDS with multi-AZ
ingress:
enabled: true
className: "nginx"
tls:
enabled: true
---
# HPA for gunicorn
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ha-bench-gunicorn-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ha-bench-gunicorn
minReplicas: 5
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
---
# HPA for workers
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ha-bench-worker-default-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ha-bench-worker-default
minReplicas: 3
maxReplicas: 15
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
⚡ NEW in v3.0.0: Unified autoscaling for web components (HPA) and workers (KEDA) with provider abstraction.
HPA: Built-in to Kubernetes ✅
KEDA: Automatically installed by install.sh, or manual installation:
kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.16.1/keda-2.16.1.yaml
This example shows autoscaling for all components - web (HPA) and workers (KEDA):
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: autoscaling-bench
namespace: production
spec:
frappeVersion: "version-15"
apps:
- name: erpnext
source: image
- name: hrms
source: image
redisConfig:
type: redis
# Component autoscaling - unified configuration for all components
componentAutoscaling:
# NGINX - HPA based on CPU utilization
nginx:
enabled: true
provider: hpa # Kubernetes built-in HPA
minReplicas: 2
maxReplicas: 10
hpa:
metric: cpu # cpu or memory
targetUtilization: 70 # Scale when CPU > 70%
scaleUpStabilization: 0 # Scale up immediately
scaleDownStabilization: 300 # Wait 5min before scaling down
# Gunicorn - HPA based on memory utilization
gunicorn:
enabled: true
provider: hpa
minReplicas: 3
maxReplicas: 15
hpa:
metric: memory
targetUtilization: 80
scaleUpStabilization: 0
scaleDownStabilization: 300
# Socket.IO - static replicas (no autoscaling)
socketio:
enabled: false
staticReplicas: 2
# Short workers - KEDA with scale-to-zero
worker-short:
enabled: true
provider: keda # KEDA for queue-based scaling
minReplicas: 0 # Scale to zero to save costs
maxReplicas: 10
pollingInterval: 10 # Check queue every 10s
cooldownPeriod: 30 # Wait 30s before scaling down
keda:
trigger: redis # Monitor Redis queue
targetValue: "2" # 2 jobs per worker
# Long workers - KEDA with minimum replicas
worker-long:
enabled: true
provider: keda
minReplicas: 1 # Always have 1 worker
maxReplicas: 5
pollingInterval: 30
cooldownPeriod: 60
keda:
trigger: redis
targetValue: "5" # 5 jobs per worker
# Default workers - static replicas
worker-default:
enabled: false
staticReplicas: 2
# Resources for components
componentResources:
nginx:
requests: { cpu: "200m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
gunicorn:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "2", memory: "2Gi" }
socketio:
requests: { cpu: "200m", memory: "512Mi" }
limits: { cpu: "1", memory: "1Gi" }
workerShort:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
workerLong:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
workerDefault:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: autoscaling-site
namespace: production
spec:
benchRef:
name: autoscaling-bench
siteName: "app.example.com"
dbConfig:
provider: mariadb
mode: shared
domain: "app.example.com"
Aggressive scale-to-zero for development environments to minimize costs:
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: dev-autoscaling
namespace: development
spec:
frappeVersion: "version-15"
apps:
- name: erpnext
source: image
# All workers scale to zero when idle
componentAutoscaling:
worker-short:
enabled: true
provider: keda
minReplicas: 0
maxReplicas: 3
pollingInterval: 5 # Check frequently
cooldownPeriod: 10 # Scale down fast
keda:
trigger: redis
targetValue: "1" # Scale up quickly
worker-long:
enabled: true
provider: keda
minReplicas: 0 # Also scale to zero
maxReplicas: 2
pollingInterval: 10
cooldownPeriod: 20
keda:
trigger: redis
targetValue: "1"
worker-default:
enabled: true
provider: keda
minReplicas: 0
maxReplicas: 2
pollingInterval: 5
cooldownPeriod: 10
keda:
trigger: redis
targetValue: "1"
# Check ScaledObjects created by KEDA
kubectl get scaledobjects -n production
# Check component scaling status
kubectl get frappebench autoscaling-bench -o jsonpath='{.status.componentScaling}' | jq
# View current HPA status
kubectl get hpa -n production
# Check queue lengths
kubectl exec -n production deployment/autoscaling-bench-redis -- \
redis-cli LLEN "rq:queue:short"
kubectl exec -n production deployment/autoscaling-bench-redis -- \
redis-cli LLEN "rq:queue:long"
# Watch worker pods scaling
kubectl get pods -n production -l component=worker-short -w
| Parameter | Description | Default | Recommended |
|---|---|---|---|
enabled |
Enable autoscaling | false |
true for production |
provider |
Scaling provider (keda or hpa) | hpa |
keda for workers, hpa for web |
minReplicas |
Minimum replicas (0 for scale-to-zero) | 1 |
0 for dev, 1+ for prod |
maxReplicas |
Maximum replicas | 10 |
Based on load |
staticReplicas |
Fixed replicas when disabled | 1 |
Based on component |
pollingInterval |
Metric check frequency (seconds) | 30 |
10-30 |
cooldownPeriod |
Wait before scale down (seconds) | 60 |
30-60 for workers |
keda.trigger |
KEDA trigger type (cpu/memory/redis) | cpu |
redis for workers |
keda.targetValue |
Jobs per worker threshold | "5" |
"2-5" for short, "5-10" for long |
hpa.metric |
HPA metric type (cpu/memory) | cpu |
cpu for web |
hpa.targetUtilization |
Target percentage (1-100) | 70 |
70-80 |
Note: The new
componentAutoscalingAPI replaces the deprecatedworkerAutoscalingAPI from v1.x.
⚡ NEW: Automated site backups using the bench backup command with full control over backup options and scheduling.
Create an immediate backup of a site:
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: backup-demo-bench
spec:
frappeVersion: "version-15"
apps:
- name: erpnext
source: image
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: backup-demo-site
spec:
benchRef:
name: backup-demo-bench
siteName: "demo.example.com"
dbConfig:
mode: shared
---
# One-time backup with files and compression
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: demo-site-backup
spec:
site: "demo.example.com" # Must match FrappeSite
withFiles: true # Include private/public files
compress: true # Compress backup files
verbose: true # Enable verbose output
Automatic daily backups at 2 AM:
---
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: demo-site-daily-backup
spec:
site: "demo.example.com"
schedule: "0 2 * * *" # Daily at 2 AM
withFiles: true
compress: true
Backup only specific DocTypes while excluding sensitive data:
---
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: demo-site-selective-backup
spec:
site: "demo.example.com"
withFiles: true
compress: true
# Include only these DocTypes
include:
- "DocType"
- "Module Def"
- "Custom Field"
- "Print Format"
# Exclude sensitive data
exclude:
- "User"
- "Role"
- "Communication"
- "Email Queue"
verbose: true
Specify custom paths for different backup components:
---
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: demo-site-custom-paths
spec:
site: "demo.example.com"
withFiles: true
compress: true
# Custom backup paths
backupPath: "/backups/daily" # Main backup directory
backupPathDB: "/backups/db" # Database files
backupPathConf: "/backups/config" # Configuration files
backupPathFiles: "/backups/public" # Public files
backupPathPrivateFiles: "/backups/private" # Private files
# Check backup status
kubectl get sitebackup
# Get detailed status
kubectl describe sitebackup demo-site-backup
# Check backup jobs
kubectl get jobs -l backup=true
# View backup logs
kubectl logs job/demo-site-backup-backup
# Check scheduled backups
kubectl get cronjob demo-site-daily-backup-backup
| Option | Description | Default |
|---|---|---|
site |
Target site name | Required |
schedule |
Cron expression for recurring backups | One-time |
withFiles |
Include private/public files | false |
compress |
Compress backup files | false |
backupPath |
Main backup directory | Default |
backupPathDB |
Database files path | Default |
backupPathConf |
Config files path | Default |
backupPathFiles |
Public files path | Default |
backupPathPrivateFiles |
Private files path | Default |
include |
DocTypes to include | All |
exclude |
DocTypes to exclude | None |
ignoreBackupConf |
Ignore backup config | false |
verbose |
Verbose output | false |
status:
phase: "Succeeded" # Pending, Running, Succeeded, Failed
lastBackup: "2024-01-15T02:00:00Z" # Last successful backup
lastBackupJob: "demo-site-backup-backup-abc123" # Job/CronJob name
message: "Backup completed successfully"
---
# Daily full backup (2 AM)
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: prod-daily-full-backup
spec:
site: "erp.example.com"
schedule: "0 2 * * *"
withFiles: true
compress: true
---
# Hourly selective backup (business data only)
apiVersion: vyogo.tech/v1alpha1
kind: SiteBackup
metadata:
name: prod-hourly-business-backup
spec:
site: "erp.example.com"
schedule: "0 * * * *"
include:
- "Sales Order"
- "Purchase Order"
- "Item"
- "Customer"
- "Supplier"
compress: true
⚡ NEW in v2.4.0: Connect to databases managed outside of Kubernetes (e.g., AWS RDS, Managed MariaDB).
Connect multiple sites to a shared external database server with default bench configurations.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: external-db-bench
spec:
frappeVersion: "version-15"
apps:
- name: erpnext
source: image
# Default DB config for all sites in this bench
dbConfig:
provider: external
host: "mariadb.production.svc.cluster.local"
port: "3306"
connectionSecretRef:
name: shared-db-creds
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: site1-external
spec:
benchRef:
name: external-db-bench
siteName: "site1.example.com"
# site1_db will be used by default (from siteName)
# Credentials will be pulled from 'shared-db-creds'
Each site with its own specific external host and credentials.
---
apiVersion: vyogo.tech/v1alpha1
kind: FrappeSite
metadata:
name: enterprise-site
spec:
benchRef:
name: dev-bench
siteName: "enterprise.example.com"
dbConfig:
provider: external
host: "dedicated-rds-instance.aws.com"
port: "3306"
connectionSecretRef:
name: enterprise-db-creds
The referenced Secret should contain at least username and password. database is optional (defaults to site name).
apiVersion: v1
kind: Secret
metadata:
name: enterprise-db-creds
type: Opaque
stringData:
username: "admin_user"
password: "secure_password"
database: "enterprise_prod" # Optional
Small, medium, and large resource tiers.
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: small-bench
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext"]'
componentReplicas:
gunicorn: 1
socketio: 1
workerDefault: 1
workerLong: 1
workerShort: 1
componentResources:
gunicorn:
requests: { cpu: "200m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
socketio:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "200m", memory: "256Mi" }
scheduler:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "200m", memory: "256Mi" }
workerDefault:
requests: { cpu: "200m", memory: "256Mi" }
limits: { cpu: "400m", memory: "512Mi" }
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: medium-bench
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms"]'
componentReplicas:
gunicorn: 3
socketio: 2
workerDefault: 2
workerLong: 1
workerShort: 1
componentResources:
gunicorn:
requests: { cpu: "500m", memory: "512Mi" }
limits: { cpu: "1", memory: "1Gi" }
socketio:
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
scheduler:
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
workerDefault:
requests: { cpu: "500m", memory: "512Mi" }
limits: { cpu: "1", memory: "1Gi" }
apiVersion: vyogo.tech/v1alpha1
kind: FrappeBench
metadata:
name: large-bench
spec:
frappeVersion: "version-15"
appsJSON: '["erpnext", "hrms"]'
componentReplicas:
gunicorn: 5
socketio: 3
workerDefault: 5
workerLong: 3
workerShort: 2
componentResources:
gunicorn:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
socketio:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
scheduler:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
workerDefault:
requests: { cpu: "1", memory: "2Gi" }
limits: { cpu: "2", memory: "4Gi" }
All examples are available in the repository under examples/:
| File | Description |
|---|---|
minimal-bench-and-site.yaml |
Minimal setup for quick testing |
autoscaling-bench.yaml |
⚡ NEW: KEDA-based worker autoscaling with scale-to-zero |
production-bench.yaml |
Production-ready bench configuration |
production-site.yaml |
Production site with TLS |
multi-tenant-bench.yaml |
Bench for multiple customer sites |
multi-tenant-sites.yaml |
Multiple sites on shared bench |
enterprise-setup.yaml |
Complete enterprise configuration |
high-availability-bench.yaml |
HA setup with multiple replicas |
dedicated-db-site.yaml |
Site with dedicated database |
custom-domain-site.yaml |
Custom domain configuration |
custom-image-bench.yaml |
Using custom container images |
resource-tiers.yaml |
Small/Medium/Large resource tiers |
basic-sitebackup.yaml |
⚡ NEW: One-time site backup |
scheduled-sitebackup.yaml |
⚡ NEW: Scheduled daily backup |
sitebackup-with-options.yaml |
⚡ NEW: Backup with files and compression |
sitebackup-selective.yaml |
⚡ NEW: Selective DocType backup |
# Clone the repository
git clone https://github.com/vyogotech/frappe-operator.git
cd frappe-operator
# Apply a specific example
kubectl apply -f examples/minimal-bench-and-site.yaml
# Or apply all examples (not recommended)
kubectl apply -f examples/
# Apply from remote URL
kubectl apply -f https://raw.githubusercontent.com/vyogotech/frappe-operator/main/examples/production-bench.yaml
# Create resources
kubectl apply -f examples/minimal-bench-and-site.yaml
# Check status
kubectl get frappebench,frappesite
# Watch for changes
kubectl get frappebench,frappesite -w
# Get details
kubectl describe frappebench <name>
kubectl describe frappesite <name>
# Check pods
kubectl get pods -l bench=<bench-name>
kubectl get pods -l site=<site-name>
# View logs
kubectl logs -l app=<component> -f
# Scale replicas
kubectl patch frappebench <name> --type=merge -p '{
"spec": {"componentReplicas": {"gunicorn": 5}}
}'
# Delete resources
kubectl delete frappesite <name>
kubectl delete frappebench <name>