helm: optional admin panel (warp-admin)
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s

admin.enabled (off by default) adds a Deployment and Service for
warp-admin on :8009, pointed at the homeserver's Service, with /healthz
probes and an optional ingress on its own host. The pods carry their own
name label so the homeserver's Service never selects them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5.5 committed 2026-10-18 14:53:23 +02:00
1 parent 487e0f410b
commit f3ef963e82
7 files changed
+229

No files matched your search

+9
View File
@@ -15,3 +15,12 @@ Reach it locally:
The signing key {{ if .Values.signingKey.existingSecret }}comes from the secret {{ .Values.signingKey.existingSecret }}{{ else }}is on the data volume, which is kept when the release is deleted{{ end }}.
Losing it means other servers no longer recognise this one.
{{- if .Values.admin.enabled }}
The admin panel is {{ if .Values.admin.ingress.enabled }}on https://{{ .Values.admin.ingress.host }}.{{ else }}reachable with:
kubectl port-forward -n {{ .Release.Namespace }} svc/{{ include "warp.admin.fullname" . }} 8009:{{ .Values.admin.service.port }}
# then browse to http://localhost:8009{{ end }}
Sign in with an account that has the admin flag.
{{- end }}
+21
View File
@@ -44,3 +44,24 @@ file:/data/warp.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(10000)&_pragma
/data/signing.key
{{- end -}}
{{- end -}}
{{/*
The admin panel has its own name label, so the homeserver's Service, whose
selector is warp.selectorLabels, never picks up its pods.
*/}}
{{- define "warp.admin.fullname" -}}
{{- printf "%s-admin" (include "warp.fullname" . | trunc 57 | trimSuffix "-") -}}
{{- end -}}
{{- define "warp.admin.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
{{ include "warp.admin.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "warp.admin.selectorLabels" -}}
app.kubernetes.io/name: {{ printf "%s-admin" (include "warp.name" .) }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: admin
{{- end -}}
@@ -0,0 +1,77 @@
{{- if .Values.admin.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "warp.admin.fullname" . }}
labels:
{{- include "warp.admin.labels" . | nindent 4 }}
spec:
# warp-admin keeps no state, so more replicas and rolling updates are fine.
replicas: {{ .Values.admin.replicas }}
selector:
matchLabels:
{{- include "warp.admin.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "warp.admin.selectorLabels" . | nindent 8 }}
{{- with .Values.admin.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.admin.podSecurityContext | nindent 8 }}
containers:
- name: warp-admin
image: "{{ .Values.admin.image.repository }}:{{ .Values.admin.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.admin.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- name: http
containerPort: 8009
protocol: TCP
env:
- name: WARP_ADMIN_LISTEN
value: ":8009"
# The homeserver's own Service: warp-admin reaches /_warp/admin
# inside the cluster, so the public ingress can leave it out.
- name: WARP_ADMIN_HOMESERVER
value: {{ printf "http://%s:%v" (include "warp.fullname" .) .Values.service.port | quote }}
- name: WARP_ADMIN_LOG_FORMAT
value: json
{{- with .Values.admin.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
livenessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 10
timeoutSeconds: 5
resources:
{{- toYaml .Values.admin.resources | nindent 12 }}
{{- with .Values.admin.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.admin.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.admin.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,31 @@
{{- if and .Values.admin.enabled .Values.admin.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "warp.admin.fullname" . }}
labels:
{{- include "warp.admin.labels" . | nindent 4 }}
{{- with .Values.admin.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.admin.ingress.className }}
ingressClassName: {{ . }}
{{- end }}
{{- with .Values.admin.ingress.tls }}
tls:
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
- host: {{ required "admin.ingress.host is required" .Values.admin.ingress.host | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "warp.admin.fullname" . }}
port:
name: http
{{- end }}
@@ -0,0 +1,17 @@
{{- if .Values.admin.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "warp.admin.fullname" . }}
labels:
{{- include "warp.admin.labels" . | nindent 4 }}
spec:
type: {{ .Values.admin.service.type }}
ports:
- name: http
port: {{ .Values.admin.service.port }}
targetPort: http
protocol: TCP
selector:
{{- include "warp.admin.selectorLabels" . | nindent 4 }}
{{- end }}
+58
View File
@@ -132,3 +132,61 @@ podAnnotations: {}
nodeSelector: {}
tolerations: []
affinity: {}
# The admin panel: warp-admin, a separate service that serves the web UI and
# proxies only the login endpoints and /_warp/admin/v1 to the homeserver's
# Service. It is optional; the homeserver runs the same without it.
admin:
enabled: false
# warp-admin keeps no state, so it can run more than one replica.
replicas: 1
# There is no published image either: build it from the repository root
# with `make admin-docker` (or
# `docker build -t <registry>/warp-admin:<tag> -f apps/admin/Dockerfile .`)
# and push it. imagePullSecrets above applies to it too.
image:
repository: warp-admin
# Defaults to the chart's appVersion.
tag: ""
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8009
# Its own ingress, on a separate host: ideally one only admins can reach
# (an internal ingress class, an IP allow-list, or SSO in front). Without
# it, reach the panel with kubectl port-forward. Since warp-admin talks to
# the homeserver inside the cluster, the main ingress can then drop the
# /_warp path.
ingress:
enabled: false
className: ""
annotations: {}
host: admin.matrix.example.org
tls: []
# - secretName: matrix-admin-tls
# hosts: [admin.matrix.example.org]
# More WARP_ADMIN_* settings; see apps/admin/README.md.
extraEnv: []
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 128Mi
# The image runs as uid 10002. securityContext above applies to the
# container as well.
podSecurityContext:
runAsUser: 10002
runAsGroup: 10002
runAsNonRoot: true
podAnnotations: {}
nodeSelector: {}
tolerations: []
affinity: {}