Kubernetes Deployment
Kubernetes deployment provides the most scalable and production-ready way to run Probo. This method is recommended for:
- Production environments
- High-availability setups
- Auto-scaling requirements
- Multi-tenant deployments
Prerequisites
Section titled “Prerequisites”- Kubernetes cluster 1.23+
- Helm 3.8+
- kubectl configured for your cluster
- Managed PostgreSQL database
- S3-compatible object storage
Quick Start
Section titled “Quick Start”-
Generate Secrets
Terminal window export ENCRYPTION_KEY=$(openssl rand -base64 32)export COOKIE_SECRET=$(openssl rand -base64 32)export PASSWORD_PEPPER=$(openssl rand -base64 32)export TRUST_TOKEN_SECRET=$(openssl rand -base64 32) -
Add Helm Repository
Terminal window # If using remote Helm chart (when available)helm repo add probo https://charts.getprobo.comhelm repo update# Or clone the repository for local chartgit clone https://github.com/getprobo/probo.gitcd probo/contrib/helm -
Install with Managed Services
Terminal window helm install my-probo ./charts/probo \--set probo.baseUrl="probo.example.com" \--set probo.encryptionKey="$ENCRYPTION_KEY" \--set probo.auth.cookieSecret="$COOKIE_SECRET" \--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \--set postgresql.enabled=false \--set postgresql.host="your-managed-db.example.com" \--set postgresql.password="your-db-password" \--set minio.enabled=false \--set s3.region="us-east-1" \--set s3.bucket="your-bucket-name" \--set s3.accessKeyId="your-access-key" \--set s3.secretAccessKey="your-secret-key" -
Access the Application
Terminal window # Port forward for testingkubectl port-forward svc/my-probo 8080:8080# Or get LoadBalancer IPkubectl get svc my-probo-haproxy-ingress
Production Deployment
Section titled “Production Deployment”Create Production Values File
Section titled “Create Production Values File”# Copy the example valuescp charts/probo/values-production.yaml.example values-production.yamlEdit values-production.yaml:
# Production configurationreplicaCount: 3
probo: baseUrl: "probo.example.com" encryptionKey: "" # Set via --set or external secrets
auth: cookieSecret: "" # Set via --set or external secrets passwordPepper: "" # Set via --set or external secrets cookieDomain: "probo.example.com" cookieSecure: true
trustAuth: tokenSecret: "" # Set via --set or external secrets cookieDomain: "probo.example.com"
cors: allowedOrigins: - "https://probo.example.com"
mailer: smtp: addr: "smtp.example.com:587" user: "smtp-username" password: "smtp-password" tlsRequired: true
# Disable demo servicespostgresql: enabled: false host: "your-managed-db.example.com" password: "your-secure-db-password"
minio: enabled: false
# Production S3 configurations3: region: "us-east-1" bucket: "your-production-bucket" accessKeyId: "your-access-key" secretAccessKey: "your-secret-key"
# Resource limitsresources: limits: cpu: "2000m" memory: "4Gi" requests: cpu: "500m" memory: "1Gi"
# Auto-scalingautoscaling: enabled: true minReplicas: 3 maxReplicas: 10 targetCPUUtilizationPercentage: 70
# Ingress configurationingress: enabled: true className: "haproxy" hosts: - host: probo.example.com paths: - path: / pathType: Prefix tls: - secretName: probo-tls hosts: - probo.example.comDeploy with Production Config
Section titled “Deploy with Production Config”helm install probo ./charts/probo \ --set probo.encryptionKey="$ENCRYPTION_KEY" \ --set probo.auth.cookieSecret="$COOKIE_SECRET" \ --set probo.auth.passwordPepper="$PASSWORD_PEPPER" \ --set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \ --set postgresql.password="$DB_PASSWORD" \ --set s3.accessKeyId="$S3_ACCESS_KEY" \ --set s3.secretAccessKey="$S3_SECRET_KEY" \ -f values-production.yamlCloud Provider Examples
Section titled “Cloud Provider Examples”AWS Deployment
Section titled “AWS Deployment”# Prerequisites:# - Amazon EKS cluster# - Amazon RDS PostgreSQL instance# - S3 bucket
helm install probo ./charts/probo \ --set probo.encryptionKey="$ENCRYPTION_KEY" \ --set probo.auth.cookieSecret="$COOKIE_SECRET" \ --set probo.auth.passwordPepper="$PASSWORD_PEPPER" \ --set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \ --set postgresql.enabled=false \ --set postgresql.host="mydb.abc123.us-east-1.rds.amazonaws.com" \ --set postgresql.password="$RDS_PASSWORD" \ --set minio.enabled=false \ --set s3.region="us-east-1" \ --set s3.bucket="my-probo-bucket" \ --set s3.accessKeyId="$AWS_ACCESS_KEY" \ --set s3.secretAccessKey="$AWS_SECRET_KEY"Google Cloud Deployment
Section titled “Google Cloud Deployment”# Prerequisites:# - GKE cluster# - Cloud SQL PostgreSQL instance# - Cloud Storage bucket with HMAC keys
helm install probo ./charts/probo \ --set probo.encryptionKey="$ENCRYPTION_KEY" \ --set probo.auth.cookieSecret="$COOKIE_SECRET" \ --set probo.auth.passwordPepper="$PASSWORD_PEPPER" \ --set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \ --set postgresql.enabled=false \ --set postgresql.host="10.0.0.5" \ --set postgresql.password="$CLOUDSQL_PASSWORD" \ --set minio.enabled=false \ --set s3.endpoint="https://storage.googleapis.com" \ --set s3.bucket="my-probo-bucket" \ --set s3.accessKeyId="$HMAC_ACCESS_KEY" \ --set s3.secretAccessKey="$HMAC_SECRET"Azure Deployment
Section titled “Azure Deployment”# Prerequisites:# - AKS cluster# - Azure Database for PostgreSQL# - Azure Blob Storage with S3 compatibility
helm install probo ./charts/probo \ --set probo.encryptionKey="$ENCRYPTION_KEY" \ --set probo.auth.cookieSecret="$COOKIE_SECRET" \ --set probo.auth.passwordPepper="$PASSWORD_PEPPER" \ --set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \ --set postgresql.enabled=false \ --set postgresql.host="mydb.postgres.database.azure.com" \ --set postgresql.password="$AZURE_DB_PASSWORD" \ --set minio.enabled=false \ --set s3.endpoint="https://mystorageaccount.blob.core.windows.net" \ --set s3.bucket="my-probo-container" \ --set s3.accessKeyId="$AZURE_ACCESS_KEY" \ --set s3.secretAccessKey="$AZURE_SECRET_KEY"Architecture
Section titled “Architecture”What Gets Deployed
Section titled “What Gets Deployed”The Helm chart deploys:
- Probo Application - Main Go binary (3+ replicas for HA)
- Chrome Headless - PDF generation service (optional)
- HAProxy Ingress - Load balancer with TCP/HTTP routing
- Services - Kubernetes services for internal communication
- ConfigMaps - Configuration data
- Secrets - Sensitive configuration
External Dependencies
Section titled “External Dependencies”Required external services:
- PostgreSQL Database - Managed database service
- S3 Storage - Object storage for files
- SMTP Server - Email notifications (optional)
Networking Architecture
Section titled “Networking Architecture”Internet ↓LoadBalancer (HAProxy Ingress)├─ Port 80 (TCP) → probo:80 (ACME/HTTP)├─ Port 443 (TCP) → probo:443 (HTTPS)└─ Host routing → probo:8080 (Backoffice) ↓Probo Pods (3+ replicas)├─ External PostgreSQL├─ External S3 Storage└─ Chrome Service (optional)Security Configuration
Section titled “Security Configuration”TLS Certificates
Section titled “TLS Certificates”Using cert-manager (Recommended)
Section titled “Using cert-manager (Recommended)”# Install cert-manager firsthelm repo add jetstack https://charts.jetstack.iohelm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set installCRDs=true
# Create ClusterIssuerapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: haproxy
# Update ingress with cert-manager annotationsingress: annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" tls: - secretName: probo-tls hosts: - probo.example.comManual Certificate Management
Section titled “Manual Certificate Management”# Create TLS secret manuallykubectl create secret tls probo-tls \ --cert=path/to/cert.pem \ --key=path/to/key.pemExternal Secrets Management
Section titled “External Secrets Management”Using External Secrets Operator
Section titled “Using External Secrets Operator”# Install External Secrets Operatorhelm repo add external-secrets https://charts.external-secrets.iohelm install external-secrets external-secrets/external-secrets \ --namespace external-secrets-system \ --create-namespace
# Create SecretStore (AWS example)apiVersion: external-secrets.io/v1beta1kind: SecretStoremetadata: name: aws-secrets-managerspec: provider: aws: service: SecretsManager region: us-east-1 auth: secretRef: accessKeyID: name: aws-creds key: access-key-id secretAccessKey: name: aws-creds key: secret-access-key
# Create ExternalSecretapiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata: name: probo-secretsspec: secretStoreRef: name: aws-secrets-manager kind: SecretStore target: name: probo-secrets data: - secretKey: encryption-key remoteRef: key: probo/encryption-key # Add other secrets...Monitoring and Observability
Section titled “Monitoring and Observability”Prometheus Metrics
Section titled “Prometheus Metrics”Enable ServiceMonitor for Prometheus Operator:
metrics: serviceMonitor: enabled: true interval: 30s labels: app: proboCustom Metrics Queries
Section titled “Custom Metrics Queries”# Application requests per secondrate(http_requests_total[5m])
# Database connection pool usageprobod_db_pool_connections_in_use / probod_db_pool_max_connections
# Memory usagecontainer_memory_usage_bytes{pod=~"probo-.*"}Log Aggregation
Section titled “Log Aggregation”Use Fluent Bit or similar to collect logs:
# Fluent Bit DaemonSet exampleapiVersion: apps/v1kind: DaemonSetmetadata: name: fluent-bitspec: template: spec: containers: - name: fluent-bit image: fluent/fluent-bit:latest volumeMounts: - name: varlog mountPath: /var/log - name: config mountPath: /fluent-bit/etcBackup and Disaster Recovery
Section titled “Backup and Disaster Recovery”Database Backups
Section titled “Database Backups”# Create backup jobkubectl create job --from=cronjob/postgres-backup backup-$(date +%Y%m%d-%H%M%S)
# Manual backupkubectl run postgres-backup --image=postgres:17 --rm -it --restart=Never -- \ pg_dump -h your-db-host -U probod probod > backup.sqlApplication Data Backup
Section titled “Application Data Backup”# Backup persistent volumes (if using local storage)kubectl get pvkubectl get pvc
# Use velero for cluster backupsvelero backup create probo-backup --include-namespaces=defaultTroubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”-
Pod startup failures:
Terminal window kubectl describe pod <pod-name>kubectl logs <pod-name> -c probo -
Database connection issues:
Terminal window # Test database connectivitykubectl run pg-test --image=postgres:17 --rm -it --restart=Never -- \pg_isready -h your-db-host -p 5432 -
Ingress not working:
Terminal window kubectl get ingresskubectl describe ingress probokubectl logs -n ingress-system <ingress-controller-pod>
Debugging Commands
Section titled “Debugging Commands”# Check all resourceskubectl get all -l app.kubernetes.io/name=probo
# View configurationkubectl get configmap probo -o yamlkubectl get secret probo -o yaml
# Check eventskubectl get events --sort-by=.metadata.creationTimestamp
# Access pod shellkubectl exec -it <pod-name> -- /bin/shUpgrading
Section titled “Upgrading”Rolling Updates
Section titled “Rolling Updates”# Update to new versionhelm upgrade probo ./charts/probo \ --set image.tag="v1.2.0" \ -f values-production.yaml
# Check rollout statuskubectl rollout status deployment/probo
# Rollback if neededhelm rollback probo 1Database Migrations
Section titled “Database Migrations”# Check migration statuskubectl logs deployment/probo | grep migration
# Run migrations manually if neededkubectl exec deployment/probo -- probod migrateHigh Availability Configuration
Section titled “High Availability Configuration”Multi-Zone Deployment
Section titled “Multi-Zone Deployment”# Spread pods across zonesaffinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - probo topologyKey: topology.kubernetes.io/zoneAuto-scaling
Section titled “Auto-scaling”autoscaling: enabled: true minReplicas: 3 maxReplicas: 20 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 80Pod Disruption Budgets
Section titled “Pod Disruption Budgets”apiVersion: policy/v1kind: PodDisruptionBudgetmetadata: name: probo-pdbspec: minAvailable: 2 selector: matchLabels: app.kubernetes.io/name: probo