Skip to content

Middleware

Deploy Middleware on Kubernetes — an open-source DORA metrics platform that measures Deployment Frequency, Lead Time for Changes, MTTR, and Change Failure Rate for engineering teams. Connects to GitHub, Jira, PagerDuty, and CI/CD pipelines to aggregate data automatically.

Persistence is required — losing /app/keys breaks all integrations

Middleware stores generated API keys for all configured integrations (GitHub, Jira, PagerDuty, etc.) in /app/keys. If the PVC is lost or persistence.enabled: false, all integration credentials are destroyed and must be reconfigured manually. Always use persistence.enabled: true in production.

Key Features

  • All four DORA metrics — Deployment Frequency, Lead Time for Changes, MTTR, Change Failure Rate
  • Single all-in-one container — frontend (Next.js), analytics API, and sync server in one image
  • Three internal services — frontend on port 3333, analytics on 9696, sync on 9697
  • PostgreSQL + Redis — bundled subcharts or external connections
  • API key persistence — integration credentials stored in PVC at /app/keys
  • Timezone-aware — configurable timezone for accurate DORA metric windows

Architecture Note

Single instance only — no horizontal scaling

Middleware runs all three services (frontend, analytics, sync) in a single pod. It cannot be horizontally scaled. Plan for at least 4 GB RAM for development and 16 GB RAM for production workloads processing large git histories and pipeline data. The startup probe allows up to 2.5 minutes for the container to initialize all internal services.

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install middleware helmforge/middleware -f values.yaml

OCI registry:

helm install middleware oci://ghcr.io/helmforgedev/helm/middleware -f values.yaml

Deployment Examples

# values.yaml — Middleware with bundled PostgreSQL and Redis subcharts
postgresql:
  enabled: true
  auth:
    database: mhq-oss
    username: middleware
    password: 'set-a-strong-password'

redis:
  enabled: true
  architecture: standalone

middleware:
  timezone: America/Sao_Paulo # affects DORA metric time windows

persistence:
  enabled: true
  size: 1Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: middleware.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Middleware with external PostgreSQL and Redis
postgresql:
  enabled: false

redis:
  enabled: false

externalDatabase:
  enabled: true
  host: postgres.database.svc.cluster.local
  port: 5432
  name: mhq-oss # default DB name — must match what you create on the server
  user: middleware
  existingSecret: middleware-db-credentials
  existingSecretPasswordKey: user-password

externalRedis:
  enabled: true
  host: redis.cache.svc.cluster.local
  port: 6379

middleware:
  timezone: UTC

persistence:
  enabled: true
  size: 1Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: middleware.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Production Middleware with resources and TLS
postgresql:
  enabled: true
  auth:
    database: mhq-oss
    username: middleware
    password: 'strong-db-password'

redis:
  enabled: true
  architecture: standalone

middleware:
  timezone: UTC
  environment: prod
  extraEnv:
    - name: NEXT_PUBLIC_APP_URL
      value: 'https://middleware.example.com'

persistence:
  enabled: true
  size: 1Gi

resources:
  requests:
    memory: 2Gi
    cpu: 500m
  limits:
    memory: 8Gi # 16GB recommended for large orgs with long git histories
    cpu: '4'

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: middleware.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: middleware-tls
      hosts:
        - middleware.example.com

Configuration Reference

Core

Parameter Type Default Description
nameOverride string "" Override the chart name.
fullnameOverride string "" Override the full release name.
commonLabels object {} Extra labels added to all resources.

Image

Parameter Type Default Description
image.repository string docker.io/middlewareeng/middleware Middleware container image.
image.tag string "0.3.1" Image tag.
image.pullPolicy string IfNotPresent Image pull policy.
imagePullSecrets array [] Pull secrets for private registries.

Middleware Configuration

Parameter Type Default Description
middleware.frontendPort integer 3333 Frontend (Next.js) listen port inside the container.
middleware.analyticsPort integer 9696 Analytics API listen port inside the container.
middleware.syncPort integer 9697 Sync server listen port inside the container.
middleware.environment string prod Application environment.
middleware.timezone string UTC Timezone for DORA metric time windows. Use IANA format (e.g. America/Sao_Paulo).
middleware.internalDbEnabled string "false" Controls the internal DB built into the image. Set to "false" when using subcharts.
middleware.internalRedisEnabled string "false" Controls the internal Redis built into the image. Set to "false" when using subcharts.
middleware.extraEnv array [] Extra environment variables for the container.
Set timezone to match your team's working hours

Middleware uses the timezone to calculate DORA metric windows (e.g. business hours for Deployment Frequency). If left at UTC and your team works in America/Sao_Paulo, deployment windows will shift by 3 hours, skewing the metrics.

External Database

Used when postgresql.enabled: false.

Parameter Type Default Description
externalDatabase.enabled boolean false Use an external PostgreSQL instead of the subchart.
externalDatabase.host string "" External PostgreSQL hostname.
externalDatabase.port integer 5432 External PostgreSQL port.
externalDatabase.name string mhq-oss Database name. Must match what you create on the server.
externalDatabase.user string middleware Database username.
externalDatabase.password string "" Database password (prefer existingSecret).
externalDatabase.existingSecret string "" Existing secret with database credentials.
externalDatabase.existingSecretPasswordKey string user-password Key inside the existing secret for the password.

External Redis

Used when redis.enabled: false.

Parameter Type Default Description
externalRedis.enabled boolean false Use an external Redis instead of subchart.
externalRedis.host string "" External Redis hostname.
externalRedis.port integer 6379 External Redis port.

Persistence

Parameter Type Default Description
persistence.enabled boolean true Enable PVC for /app/keys (API keys for all integrations).
persistence.size string 1Gi PVC size. Integration keys are small — 1Gi is sufficient.
persistence.storageClass string "" StorageClass for the PVC.
persistence.accessModes array [ReadWriteOnce] PVC access modes.
persistence.existingClaim string "" Use an existing PVC.

Service

Parameter Type Default Description
service.type string ClusterIP Service type.
service.port integer 80 Service port. Routes to the frontend on 3333.
service.annotations object {} Annotations for the Service.

Ingress

Parameter Type Default Description
ingress.enabled boolean false Enable an Ingress resource.
ingress.ingressClassName string traefik Ingress class name.
ingress.annotations object {} Annotations for the Ingress (e.g. cert-manager).
ingress.hosts array [] Ingress host and path rules.
ingress.tls array [] TLS configuration.

Probes

Parameter Type Default Description
probes.startup.enabled boolean true Enable startup probe.
probes.startup.initialDelaySeconds integer 30 Initial delay before first startup check.
probes.startup.periodSeconds integer 5 Startup probe period.
probes.startup.failureThreshold integer 30 Max failures (30 × 5s = 2.5 min total startup tolerance).
probes.liveness.enabled boolean true Enable liveness probe.
probes.liveness.periodSeconds integer 15 Liveness probe period.
probes.liveness.failureThreshold integer 3 Liveness probe failure threshold.
probes.readiness.enabled boolean true Enable readiness probe.
probes.readiness.periodSeconds integer 10 Readiness probe period.
probes.readiness.failureThreshold integer 3 Readiness probe failure threshold.

Subcharts

Parameter Type Default Description
postgresql.enabled boolean true Deploy bundled PostgreSQL subchart.
postgresql.auth.database string mhq-oss Database name for Middleware.
postgresql.auth.username string middleware Database username.
postgresql.auth.password string "" Database password. Auto-generated if empty.
redis.enabled boolean true Deploy bundled Redis subchart.
redis.architecture string standalone Redis architecture.

Resources and Security

Parameter Type Default Description
resources object {} CPU and memory requests and limits.
podSecurityContext object {} Pod-level security context.
securityContext object {} Container-level security context.

Scheduling

Parameter Type Default Description
nodeSelector object {} Node selector for scheduling.
tolerations array [] Tolerations for scheduling.
affinity object {} Affinity rules.
topologySpreadConstraints array [] Topology spread constraints.
priorityClassName string "" PriorityClass for the pod.
terminationGracePeriodSeconds integer 30 Termination grace period.
podLabels object {} Extra labels for the pod.
podAnnotations object {} Extra annotations for the pod.

Extra

Parameter Type Default Description
extraVolumes array [] Extra volumes to attach to the pod.
extraVolumeMounts array [] Extra volume mounts for the container.
extraManifests array [] Extra Kubernetes manifests deployed alongside the chart.

More Information