--- apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: mastodon namespace: mastodon-application spec: interval: 5m timeout: 15m chart: spec: chart: . sourceRef: kind: GitRepository name: mastodon-chart namespace: mastodon-application interval: 1m dependsOn: - name: cloudnative-pg namespace: postgresql-system - name: redis-ha namespace: redis-system - name: eck-operator namespace: elasticsearch-system values: # Override Mastodon image version to 4.5.0 image: repository: ghcr.io/mastodon/mastodon tag: v4.5.3 pullPolicy: IfNotPresent # Mastodon Configuration mastodon: # Domain Configuration - CRITICAL: Never change LOCAL_DOMAIN after federation starts local_domain: "mastodon.keyboardvagabond.com" web_domain: "mastodon.keyboardvagabond.com" # Trust pod network and VLAN network for Rails host authorization # - 10.244.0.0/16: Cilium CNI pod network (internal pod-to-pod communication) # - 10.132.0.0/24: NetCup Cloud VLAN network (NGINX Ingress runs in hostNetwork mode) # - 127.0.0.1: Localhost (for health checks and internal connections) # Note: Cloudflare IPs not needed - NGINX Ingress handles Cloudflare connections # and forwards with X-Forwarded-* headers. Mastodon sees NGINX Ingress source IPs (VLAN). trusted_proxy_ip: "10.244.0.0/16,10.132.0.0/24,127.0.0.1" # Single User Mode - Enable initially for setup single_user_mode: false # Secrets Configuration secrets: existingSecret: mastodon-secrets # S3 Configuration (Backblaze B2) s3: enabled: true existingSecret: mastodon-secrets bucket: mastodon-bucket region: eu-central-003 endpoint: alias_host: mm.keyboardvagabond.com # SMTP Configuration smtp: # Use separate secret to avoid key conflicts with database password existingSecret: mastodon-smtp-secrets server: port: 587 from_address: mastodon@mail.keyboardvagabond.com domain: mail.keyboardvagabond.com delivery_method: smtp auth_method: plain enable_starttls: auto # Monitoring Configuration metrics: statsd: address: "" bind: "0.0.0.0" # OpenTelemetry Configuration - Enabled for span metrics otel: exporter_otlp_endpoint: http://openobserve-collector-agent-collector.openobserve-collector.svc.cluster.local:4318 service_name: mastodon # Web Component Configuration web: replicas: "2" maxThreads: "10" workers: "4" autoscaling: enabled: true minReplicas: 2 maxReplicas: 4 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 80 resources: requests: cpu: 250m # Reduced from 1000m - actual usage is ~25m memory: 1.5Gi # Reduced from 2Gi - actual usage is ~1.4Gi limits: cpu: 1000m # Reduced from 2000m but still plenty of headroom memory: 3Gi # Reduced from 4Gi but still adequate nodeSelector: {} tolerations: [] affinity: {} # Sidekiq Component Configuration sidekiq: replicas: 2 autoscaling: enabled: true minReplicas: 1 maxReplicas: 4 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 80 resources: requests: cpu: 250m # Reduced from 500m for resource optimization memory: 768Mi # Reduced from 1Gi but adequate for sidekiq limits: cpu: 750m # Reduced from 1000m but still adequate memory: 1.5Gi # Reduced from 2Gi but still adequate nodeSelector: {} tolerations: [] affinity: {} # Streaming Component Configuration streaming: replicaCount: 2 autoscaling: enabled: true minReplicas: 2 maxReplicas: 3 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 80 resources: requests: cpu: 250m memory: 512Mi limits: cpu: 500m memory: 1Gi nodeSelector: {} tolerations: [] affinity: {} # Storage Configuration persistence: assets: # Use S3 for media storage instead of local persistence enabled: false system: enabled: true storageClassName: longhorn-retain size: 10Gi accessMode: ReadWriteMany # Enable S3 backup for Mastodon system storage (daily + weekly) labels: recurring-job.longhorn.io/source: "enabled" recurring-job-group.longhorn.io/longhorn-s3-backup: "enabled" recurring-job-group.longhorn.io/longhorn-s3-backup-weekly: "enabled" # External Authentication Configuration externalAuth: # OIDC Configuration (Authentik) - Correct location per official values.yaml oidc: enabled: true display_name: "Keyboard Vagabond SSO" issuer: https://auth.keyboardvagabond.com/application/o/mastodon/ redirect_uri: https://mastodon.keyboardvagabond.com/auth/openid_connect/callback discovery: true scope: "openid,profile,email" uid_field: preferred_username existingSecret: mastodon-secrets assume_email_is_verified: true # CronJob Configuration cronjobs: # Media removal CronJob configuration media: # Retain fewer completed jobs to reduce clutter successfulJobsHistoryLimit: 1 # Reduced from default 3 to 1 failedJobsHistoryLimit: 1 # Keep at 1 for debugging failed runs # PostgreSQL Configuration (External) - Correct structure per official values.yaml postgresql: enabled: false # Required when postgresql.enabled is false postgresqlHostname: postgresql-shared-rw.postgresql-system.svc.cluster.local postgresqlPort: 5432 # If using a connection pooler such as pgbouncer, please specify a hostname/IP # that serves as a "direct" connection to the database, rather than going # through the connection pooler. This is required for migrations to work # properly. direct: hostname: postgresql-shared-rw.postgresql-system.svc.cluster.local port: 5432 database: mastodon_production auth: database: mastodon_production username: mastodon existingSecret: mastodon-secrets # Options for a read-only replica. # If enabled, mastodon uses existing defaults for postgres for these values as well. # NOTE: This feature is only available on Mastodon v4.2+ # Documentation for more information on this feature: # https://docs.joinmastodon.org/admin/scaling/#read-replicas readReplica: hostname: postgresql-shared-ro.postgresql-system.svc.cluster.local port: 5432 auth: database: mastodon_production username: mastodon existingSecret: mastodon-secrets # Redis Configuration (External) - Correct structure per official values.yaml redis: enabled: false hostname: redis-ha-haproxy.redis-system.svc.cluster.local port: 6379 auth: existingSecret: mastodon-secrets # Elasticsearch Configuration - Disable internal deployment (using external) elasticsearch: enabled: false # External Elasticsearch Configuration hostname: elasticsearch-es-http.elasticsearch-system.svc.cluster.local port: 9200 # HTTP scheme - TLS is disabled for internal cluster communication tls: false preset: single_node_cluster # Elasticsearch authentication user: mastodon # Use separate secret to avoid conflict with PostgreSQL password key existingSecret: mastodon-elasticsearch-credentials # Ingress Configuration (Handled separately) ingress: enabled: false # Service Configuration service: type: ClusterIP web: port: 3000 streaming: port: 4000