declarative relay deployment on hetzner relay-eval.waow.tech
atproto relay
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

add jetstream panels to grafana dashboard, commit deploy manifests

- dashboard: jetstream row with subscribers, events/sec, bytes/sec panels
- commit jetstream helm values, ingress, and servicemonitor manifests
- README: fix stale deploy description, remove redundant restart step

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

zzstoatzz 12576e31 3ed4fc10

+191 -8
+2 -8
README.md
··· 117 117 just init # terraform init 118 118 just infra # creates a CPX31 in Ashburn (~$15/mo) with k3s via cloud-init 119 119 just kubeconfig # waits for k3s, pulls kubeconfig (~2 min) 120 - just deploy # installs cert-manager, postgresql, relay, ingress 120 + just deploy # installs cert-manager, postgresql, relay, jetstream, monitoring 121 121 ``` 122 122 123 123 point a DNS A record at the server IP (`just server-ip`) before running deploy, so the Let's Encrypt HTTP-01 challenge succeeds. ··· 125 125 after deploy, seed the relay with the network's PDS hosts: 126 126 127 127 ```bash 128 - just bootstrap 129 - ``` 130 - 131 - then restart the relay pod so the slurper picks up the new hosts: 132 - 133 - ```bash 134 - kubectl rollout restart deploy/relay -n relay 128 + just bootstrap # pulls hosts from upstream + restarts relay so slurper picks them up 135 129 ``` 136 130 137 131 ### available commands
+24
deploy/jetstream-ingress.yaml
··· 1 + apiVersion: networking.k8s.io/v1 2 + kind: Ingress 3 + metadata: 4 + name: jetstream 5 + namespace: relay 6 + annotations: 7 + cert-manager.io/cluster-issuer: letsencrypt-prod 8 + spec: 9 + ingressClassName: traefik 10 + tls: 11 + - hosts: 12 + - JETSTREAM_DOMAIN_PLACEHOLDER 13 + secretName: jetstream-tls 14 + rules: 15 + - host: JETSTREAM_DOMAIN_PLACEHOLDER 16 + http: 17 + paths: 18 + - path: / 19 + pathType: Prefix 20 + backend: 21 + service: 22 + name: jetstream 23 + port: 24 + number: 6008
+15
deploy/jetstream-servicemonitor.yaml
··· 1 + apiVersion: monitoring.coreos.com/v1 2 + kind: ServiceMonitor 3 + metadata: 4 + name: jetstream 5 + namespace: monitoring 6 + spec: 7 + selector: 8 + matchLabels: 9 + app.kubernetes.io/name: jetstream 10 + namespaceSelector: 11 + matchNames: 12 + - relay 13 + endpoints: 14 + - port: metrics 15 + interval: 30s
+53
deploy/jetstream-values.yaml
··· 1 + # bjw-s/app-template helm values for Jetstream 2 + # converts the relay's CBOR firehose into JSON WebSocket events 3 + # schema: https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template 4 + 5 + controllers: 6 + jetstream: 7 + containers: 8 + main: 9 + image: 10 + repository: ghcr.io/bluesky-social/jetstream 11 + tag: sha-05c89f0 12 + env: 13 + JETSTREAM_WS_URL: "wss://relay.waow.tech/xrpc/com.atproto.sync.subscribeRepos" 14 + JETSTREAM_LISTEN_ADDR: ":6008" 15 + JETSTREAM_METRICS_LISTEN_ADDR: ":6009" 16 + JETSTREAM_DATA_DIR: "/data" 17 + JETSTREAM_EVENT_TTL: "24h" 18 + JETSTREAM_LIVENESS_TTL: "15s" 19 + probes: 20 + liveness: &probes 21 + enabled: true 22 + custom: true 23 + spec: 24 + httpGet: 25 + path: / 26 + port: &wsport 6008 27 + initialDelaySeconds: 10 28 + periodSeconds: 10 29 + timeoutSeconds: 3 30 + failureThreshold: 5 31 + readiness: *probes 32 + resources: 33 + requests: 34 + memory: 128Mi 35 + cpu: 50m 36 + limits: 37 + memory: 512Mi 38 + 39 + service: 40 + jetstream: 41 + controller: jetstream 42 + ports: 43 + http: 44 + port: *wsport 45 + metrics: 46 + port: 6009 47 + 48 + persistence: 49 + data: 50 + enabled: true 51 + type: persistentVolumeClaim 52 + accessMode: ReadWriteOnce 53 + size: 5Gi
+97
deploy/relay-dashboard.json
··· 191 191 "refId": "A" 192 192 } 193 193 ] 194 + }, 195 + { 196 + "title": "jetstream", 197 + "type": "row", 198 + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 24 }, 199 + "collapsed": false, 200 + "panels": [] 201 + }, 202 + { 203 + "title": "jetstream subscribers", 204 + "type": "stat", 205 + "gridPos": { "h": 8, "w": 6, "x": 0, "y": 25 }, 206 + "datasource": { "type": "prometheus", "uid": "prometheus" }, 207 + "fieldConfig": { 208 + "defaults": { 209 + "color": { "mode": "thresholds" }, 210 + "thresholds": { 211 + "steps": [ 212 + { "color": "red", "value": null }, 213 + { "color": "green", "value": 1 } 214 + ] 215 + } 216 + }, 217 + "overrides": [] 218 + }, 219 + "options": { 220 + "colorMode": "value", 221 + "graphMode": "area", 222 + "reduceOptions": { "calcs": ["lastNotNull"] } 223 + }, 224 + "targets": [ 225 + { 226 + "expr": "jetstream_subscribers_connected", 227 + "legendFormat": "connected", 228 + "refId": "A" 229 + } 230 + ] 231 + }, 232 + { 233 + "title": "jetstream events/sec", 234 + "type": "timeseries", 235 + "gridPos": { "h": 8, "w": 9, "x": 6, "y": 25 }, 236 + "datasource": { "type": "prometheus", "uid": "prometheus" }, 237 + "fieldConfig": { 238 + "defaults": { 239 + "unit": "ops", 240 + "color": { "mode": "palette-classic" }, 241 + "custom": { 242 + "fillOpacity": 15, 243 + "lineWidth": 2, 244 + "spanNulls": false 245 + } 246 + }, 247 + "overrides": [] 248 + }, 249 + "targets": [ 250 + { 251 + "expr": "sum(rate(jetstream_events_emitted_total[5m]))", 252 + "legendFormat": "emitted (from relay)", 253 + "refId": "A" 254 + }, 255 + { 256 + "expr": "sum(rate(jetstream_events_delivered_total[5m]))", 257 + "legendFormat": "delivered (to subscribers)", 258 + "refId": "B" 259 + } 260 + ] 261 + }, 262 + { 263 + "title": "jetstream bytes delivered/sec", 264 + "type": "timeseries", 265 + "gridPos": { "h": 8, "w": 9, "x": 15, "y": 25 }, 266 + "datasource": { "type": "prometheus", "uid": "prometheus" }, 267 + "fieldConfig": { 268 + "defaults": { 269 + "unit": "Bps", 270 + "color": { "mode": "palette-classic" }, 271 + "custom": { 272 + "fillOpacity": 15, 273 + "lineWidth": 2, 274 + "spanNulls": false 275 + } 276 + }, 277 + "overrides": [] 278 + }, 279 + "targets": [ 280 + { 281 + "expr": "sum(rate(jetstream_bytes_delivered_total[5m]))", 282 + "legendFormat": "to subscribers", 283 + "refId": "A" 284 + }, 285 + { 286 + "expr": "sum(rate(jetstream_bytes_emitted_total[5m]))", 287 + "legendFormat": "emitted (total)", 288 + "refId": "B" 289 + } 290 + ] 194 291 } 195 292 ], 196 293 "schemaVersion": 39,