rust-web-server 18.7.0

Single-binary web server and reverse proxy: automatic HTTPS (Let's Encrypt), HTTP/1.1, HTTP/2 and HTTP/3, load balancing, auth and rate limiting, configured in one TOML file. Also a Rust library: routing, middleware, MCP server, ORM, background jobs. No hyper, no Tower; HTTP/2 and HTTP/3 framing via h2 and quinn.
Documentation
# Default values for the rws chart.
# Mirrors the YAML documented at docs/deployment/kubernetes.md — see that
# page for the semantics behind each field (health probes, graceful
# shutdown, RWS_CONFIG_* env vars, autoscaling on custom Prometheus metrics).

replicaCount: 3

image:
  repository: ghcr.io/bohdaq/rws
  # Empty = the chart's appVersion (the rws release the chart was published with).
  tag: ""
  pullPolicy: IfNotPresent

imagePullSecrets: []

nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Set to true to have this chart create a ServiceAccount (e.g. for
  # workload identity / IRSA). When false, `serviceAccount.name` is used
  # as-is (empty means the namespace's "default" ServiceAccount).
  create: false
  annotations: {}
  name: ""

# Pod-level annotations.
podAnnotations: {}

metrics:
  # prometheus.io/scrape, /path, /port and /scheme on the pod, so a Prometheus
  # using annotation-based discovery scrapes GET /metrics (over HTTPS when
  # tls.enabled) — see docs/deployment/observability.md.
  podAnnotations: true
  # A prometheus-operator ServiceMonitor (needs its CRDs in the cluster).
  serviceMonitor:
    enabled: false
    interval: 30s
    scrapeTimeout: 10s
    labels: {}
    # Used when tls.enabled: the pod certificate is usually issued for the
    # public name, not the pod IP Prometheus scrapes.
    tlsConfig:
      insecureSkipVerify: true

podLabels: {}

# Give in-flight requests time to complete after SIGTERM before Kubernetes
# sends SIGKILL — see docs/deployment/kubernetes.md#graceful-shutdown.
terminationGracePeriodSeconds: 30

containerPort: 7878

# RWS_CONFIG_* environment variables set on the container. Add any other
# RWS_CONFIG_* var documented in CLAUDE.md / docs/ here as a plain
# key/value pair — this map is rendered directly into `env:`.
env:
  RWS_CONFIG_IP: "0.0.0.0"
  RWS_CONFIG_PORT: "7878"
  RWS_CONFIG_THREAD_COUNT: "4"
  RWS_CONFIG_LOG_FORMAT: "json"

# Additional env vars as a raw {name, value} / {name, valueFrom} list,
# appended after `env` above — for anything that doesn't fit a plain
# string value (e.g. a Secret/ConfigMap reference).
extraEnv: []
# extraEnv:
#   - name: RWS_CONFIG_RATE_LIMIT_MAX_REQUESTS
#     value: "1000"
#   - name: MCP_TOKEN
#     valueFrom:
#       secretKeyRef:
#         name: rws-mcp-token
#         key: token

# Whole Secrets/ConfigMaps to import as env vars via envFrom.
envFrom: []

# TLS is on by default, matching docs/deployment/kubernetes.md — set
# tls.enabled to false to run plain HTTP/1.1 (e.g. behind a TLS-terminating
# load balancer or ingress controller).
tls:
  enabled: true
  # Must already exist in the release namespace, containing `tls.crt` and
  # `tls.key` (e.g. `kubectl create secret tls rws-tls --cert=... --key=...`).
  secretName: rws-tls
  certPath: /tls/tls.crt
  keyPath: /tls/tls.key
  mountPath: /tls

# rws also serves HTTP/3 over QUIC (UDP) on the same port as HTTP/2 when
# built with the default `http3` feature. Set to false if your image was
# built with `--features http2` (no QUIC) or `--features http1` (no TLS).
quic:
  enabled: true

service:
  type: ClusterIP
  # Port "https" when tls.enabled, else port "http".
  httpsPort: 443
  httpPort: 80
  quicPort: 443
  annotations: {}

resources:
  requests:
    cpu: 100m
    memory: 64Mi
  limits:
    cpu: 500m
    memory: 256Mi

livenessProbe:
  path: /healthz
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 3
  failureThreshold: 3

readinessProbe:
  path: /readyz
  initialDelaySeconds: 2
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 2

# An Ingress in front of the Service. With tls.enabled the pods speak HTTPS,
# so the controller must too: the chart adds ingress-nginx's
# backend-protocol annotation; set your controller's equivalent otherwise.
# Behind an Ingress you usually want tls.enabled=false and quic.enabled=false
# and TLS terminated by the controller (ingress.tls).
ingress:
  enabled: false
  className: ""
  annotations: {}
  hosts:
    - host: rws.example.com
      paths:
        - path: /
          pathType: Prefix
  tls: []
  #  - secretName: rws-example-tls
  #    hosts: [rws.example.com]

podDisruptionBudget:
  enabled: true
  minAvailable: 2

# HorizontalPodAutoscaler — disabled by default since it manages
# `replicaCount` itself (enabling it makes the Deployment omit
# `spec.replicas` so the HPA is the sole source of truth).
autoscaling:
  enabled: false
  minReplicas: 2
  maxReplicas: 20
  # Set to null/0 to omit the CPU metric entirely.
  targetCPUUtilizationPercentage: 70
  # Requests per second per pod, from the custom metrics API. rws exports
  # the counter rws_requests_total; the Prometheus Adapter rule in
  # helm/prometheus-adapter-values.yaml turns it into this rate.
  customMetric:
    enabled: false
    name: rws_requests_per_second
    averageValue: "500"

nodeSelector: {}
tolerations: []
affinity: {}

# Pod-level securityContext (fsGroup, etc.)
podSecurityContext: {}

# Container-level securityContext (runAsNonRoot, readOnlyRootFilesystem, etc.)
securityContext: {}