Skip to content

Zammad (Ticketing)

Namespace: tickets | URL: https://support.astaup.de | Chart: zammad/zammad v15.6.1 Manifests: k8s/clusters/main/apps/tickets/

Components

ComponentSourceNotes
Zammad (nginx, rails, websocket, scheduler)Helm chart
PostgreSQLCNPG Cluster (zammad-db, 4 instances)External to chart
Redis, Elasticsearch, MemcachedHelm subcharts
S3 StorageCOSI BucketClaim (Garage)External to chart

Cluster Prerequisites

CNPG operator, Istio ambient, cert-manager (letsencrypt ClusterIssuer), MetalLB, COSI controller with Garage driver, mittwald secret-generator, StorageClass ssd-replicated-retain, BucketClass garage-ssd.

Secrets

All secrets are auto-generated. No manual creation needed for a fresh deploy.

SecretCreated by
zammad-db-appCNPG operator
zammad-redis-passsecret-generator (hex, 40 chars)
zammad-autowizardsecret-generator (base64, 64 chars)
zammad-bucket-credentialsCOSI BucketAccess
zammad-s3-configzammad-s3-secret-creator Job (transforms COSI creds)
support.astaup.de-tlscert-manager

Gotchas

Passwords must not contain URL-special characters

Zammad parses credentials from connection strings. Characters like @, :, /, ?, # will break parsing. The secret-generator uses hex encoding for Redis to avoid this. CNPG defaults are safe too, but keep this in mind if you ever set passwords manually. See zammad-helm#251.

PodSecurity vs. privileged init containers

Two Helm chart init containers are disabled because they require privileged mode:

  • volumePermissions -- worked around with tmpDirVolume.emptyDir.medium: Memory (memory-backed tmpfs avoids permission issues)
  • Elasticsearch sysctlImage (sets vm.max_map_count) -- Elasticsearch runs without it but may underperform under heavy load

Redis does not support mTLS

The namespace uses Istio ambient with default-deny. Redis can't do mTLS, so mesh.yaml has a PeerAuthentication (PERMISSIVE, port 6379 DISABLE) and a DestinationRule (TLS DISABLE) to exempt it. If Redis connections fail after pod restarts, check these first.

Istio HBONE port on subchart NetworkPolicies

The Helm subcharts for Redis, Elasticsearch, and Memcached ship their own NetworkPolicy. These block Istio ambient's HBONE tunnel (port 15008) by default. Each subchart has networkPolicy.extraIngress allowing port 15008. If you add another subchart with a NetworkPolicy, add the same exception or pod-to-pod traffic will silently fail.

S3 secret requires a transformation Job

COSI creates zammad-bucket-credentials with a BucketInfo JSON blob. Zammad expects an S3 URL like https://KEY:SECRET@HOST/BUCKET?force_path_style=true. The zammad-s3-secret-creator Job bridges this gap. It's a one-shot Job -- if you rotate S3 credentials, delete it and let Flux recreate it:

bash
kubectl delete job zammad-s3-secret-creator -n tickets
flux reconcile kustomization zammad-overlay -n tickets

CNPG cluster has Istio disabled

db.yaml has istio.io/dataplane-mode: none. CNPG manages its own replication; Istio ambient interferes with it. Don't remove this label.

PostgreSQL connects via -rw service

The Helm values point to zammad-db-rw (CNPG read-write service, always routes to primary). CNPG also creates -ro and -r services, but Zammad needs read-write.

bitnamilegacy/* subchart images

The Helm chart's default values use bitnamilegacy/* images for all subcharts (Elasticsearch, Redis, Memcached, PostgreSQL, MinIO). This is the chart's workaround for Bitnami discontinuing free versioned container images in Sept 2025 (bitnami/containers#83267). These legacy images are archived and unmaintained -- they receive no security patches. Watch for the upstream chart to migrate to alternative base images.

Networking

  • Gateway: Istio Gateway API, MetalLB IPs 141.89.58.194 / 2001:638:807:3a:ab20:c4f2:a109:a875
  • DNS: A + AAAA records for support.astaup.de pointing to the above
  • TLS: Auto-renewed via cert-manager + Let's Encrypt
  • Mesh: Default-deny AuthorizationPolicy; explicit allow rules per service in mesh.yaml

Post-Deploy

Initial setup (admin account, email/SMTP, organization) is done through the web UI on first launch.