1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 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
# Kubernetes Gateway API controller — needs an image built with the
# `gateway-api` feature and the Gateway API CRDs (standard channel, v1.6)
# installed; see docs/deployment/kubernetes-gateway-api.md. Creates the
# GatewayClass, a ServiceAccount (whatever serviceAccount.create says) and
# the RBAC the controller needs. Every Gateway gets its own Service.
gatewayAPI:
enabled: false
className: rws
controllerName: rws8.tech/gateway-controller
# Container ports for Gateway listeners (each Gateway Service maps a
# listener port to one of these).
portRange: "10000-10999"
# Type of each Gateway's Service.
serviceType: LoadBalancer
# shared: this release's pods serve every Gateway. provisioned: each
# Gateway gets its own Deployment of rws pods (in this namespace, this
# image and ServiceAccount); this release's pods only run the controller.
mode: shared
service:
type: ClusterIP
# Port "https" when tls.enabled, else port "http".
httpsPort: 443
httpPort: 80
quicPort: 443
annotations:
# With gatewayAPI.enabled the CPU limit is left out (a gateway serving every
# Gateway's traffic shouldn't be throttled); the rest applies as set.
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: