chore: initial Jitsi-Meet k3s scaffold for darkemberserver
Some checks failed
deploy / deploy (push) Failing after 3s
Some checks failed
deploy / deploy (push) Failing after 3s
Self-hosted Jitsi instance at meet.it.financeflow.de — avoids the meet.jit.si moderator-auth wall. Four components (web/prosody/jicofo/jvb) as raw k3s manifests, same deploy pattern as Embertime (Gitea Actions + kubectl apply + KUBECONFIG_B64 secret). JVB uses hostNetwork + UDP 10000 for media — requires router forward. Component passwords live in a kubectl-applied Secret (not in git); generate-secrets.sh produces a fresh manifest. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
6efce0c8f1
66
.gitea/workflows/deploy.yml
Normal file
66
.gitea/workflows/deploy.yml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
name: deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install kubectl
|
||||||
|
uses: azure/setup-kubectl@v4
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
|
- name: Configure kubectl from secret
|
||||||
|
run: |
|
||||||
|
mkdir -p "$HOME/.kube"
|
||||||
|
echo "${{ secrets.KUBECONFIG_B64 }}" | base64 -d > "$HOME/.kube/config"
|
||||||
|
chmod 600 "$HOME/.kube/config"
|
||||||
|
kubectl config current-context
|
||||||
|
|
||||||
|
# __PUBLIC_IP__ placeholder in jvb manifest needs the actual public
|
||||||
|
# IP of darkember. Inject from a repo secret so the manifest stays
|
||||||
|
# generic in git.
|
||||||
|
- name: Patch JVB public IP
|
||||||
|
run: |
|
||||||
|
test -n "${{ secrets.DARKEMBER_PUBLIC_IP }}" || (echo "secret DARKEMBER_PUBLIC_IP missing" && exit 1)
|
||||||
|
sed -i "s|__PUBLIC_IP__|${{ secrets.DARKEMBER_PUBLIC_IP }}|g" infra/k3s/60-jvb.yaml
|
||||||
|
|
||||||
|
- name: Apply manifests
|
||||||
|
# 20-secrets.yaml is intentionally NOT applied — secret must be
|
||||||
|
# created out-of-band (see scripts/generate-secrets.sh) so we
|
||||||
|
# don't overwrite real values with placeholders.
|
||||||
|
run: |
|
||||||
|
kubectl apply -f infra/k3s/00-namespace.yaml
|
||||||
|
kubectl apply -f infra/k3s/10-config.yaml
|
||||||
|
kubectl apply -f infra/k3s/30-prosody.yaml
|
||||||
|
kubectl apply -f infra/k3s/40-jicofo.yaml
|
||||||
|
kubectl apply -f infra/k3s/50-web.yaml
|
||||||
|
kubectl apply -f infra/k3s/60-jvb.yaml
|
||||||
|
kubectl apply -f infra/k3s/70-ingress.yaml
|
||||||
|
|
||||||
|
- name: Wait for rollout
|
||||||
|
run: |
|
||||||
|
kubectl -n jitsi rollout status deployment/prosody --timeout=3m
|
||||||
|
kubectl -n jitsi rollout status deployment/jicofo --timeout=3m
|
||||||
|
kubectl -n jitsi rollout status deployment/jitsi-web --timeout=3m
|
||||||
|
kubectl -n jitsi rollout status deployment/jvb --timeout=3m
|
||||||
|
|
||||||
|
- name: Smoke-check
|
||||||
|
run: |
|
||||||
|
for i in 1 2 3 4 5; do
|
||||||
|
if curl -fsS -o /dev/null -w "%{http_code}\n" https://meet.it.financeflow.de/ | grep -q "200\|301\|302"; then
|
||||||
|
echo "meet.it.financeflow.de is up"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
echo "smoke-check failed"
|
||||||
|
exit 1
|
||||||
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Real secrets — must live out-of-band, not in git
|
||||||
|
infra/k3s/20-secrets.yaml
|
||||||
|
infra/k3s/*-secrets.yaml
|
||||||
|
*.secret
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
53
CLAUDE.md
Normal file
53
CLAUDE.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# jitsi-meet — Projekt-Kontext für Claude-Sessions
|
||||||
|
|
||||||
|
Selbst-gehostete Jitsi-Meet-Instanz auf darkemberserver via k3s. Same-Cluster-Deploy wie Embertime/Gitea/Headscale. Repo unter `~/Developer/jitsi-meet/`, Public-URL `https://meet.it.financeflow.de`.
|
||||||
|
|
||||||
|
Zweck: privater Online-Meeting-Service ohne Google-/GitHub-Login-Zwang (das öffentliche meet.jit.si verlangt seit 2024/25 Moderator-Auth). Wird unter anderem von Embertime als Default-Meeting-URL referenziert.
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
|
||||||
|
Vier Container nach offiziellem `jitsi/docker-jitsi-meet`-Pattern:
|
||||||
|
|
||||||
|
- **web** (`jitsi/web`): Nginx + Meet-Frontend, exposed via Ingress :443
|
||||||
|
- **prosody** (`jitsi/prosody`): XMPP-Server, cluster-intern
|
||||||
|
- **jicofo** (`jitsi/jicofo`): Focus/Conference-Manager, cluster-intern
|
||||||
|
- **jvb** (`jitsi/jvb`): Videobridge — `hostNetwork: true` damit UDP 10000 direkt auf Node-Interface bindet (alternativ Sub-LoadBalancer, aber unzuverlässig)
|
||||||
|
|
||||||
|
Inter-Component-Auth über shared XMPP-Component-Secrets (im Kubernetes-Secret, nicht im Repo).
|
||||||
|
|
||||||
|
## Wichtigste Dateien
|
||||||
|
|
||||||
|
- `infra/k3s/00-namespace.yaml` — Namespace `jitsi`
|
||||||
|
- `infra/k3s/10-config.yaml` — ConfigMap mit nicht-sensiblen Env-Vars (XMPP-Domains, PUBLIC_URL, ...)
|
||||||
|
- `infra/k3s/20-secrets.yaml.example` — Vorlage; **echte Secrets manuell erzeugen** via `scripts/generate-secrets.sh`, dann `kubectl apply -f infra/k3s/20-secrets.yaml` einmalig out-of-band
|
||||||
|
- `infra/k3s/30-prosody.yaml`, `40-jicofo.yaml`, `50-web.yaml`, `60-jvb.yaml` — Component-Deployments + Services
|
||||||
|
- `infra/k3s/70-ingress.yaml` — Ingress mit cert-manager (letsencrypt-prod ClusterIssuer)
|
||||||
|
- `.gitea/workflows/deploy.yml` — `kubectl apply -f infra/k3s/...` auf Push nach main
|
||||||
|
- `scripts/generate-secrets.sh` — generiert random Component-Passwords + schreibt `20-secrets.yaml`
|
||||||
|
|
||||||
|
## Setup-Schritte (einmalig)
|
||||||
|
|
||||||
|
1. **DNS**: A-Record `meet.it.financeflow.de` → öffentliche IP von darkemberserver
|
||||||
|
2. **Firewall/Router**: UDP-Port **10000** auf darkember-Node forwarden (kritisch! ohne das funktioniert nur Audio, kein Video)
|
||||||
|
3. **Secrets generieren + applyen**:
|
||||||
|
```bash
|
||||||
|
./scripts/generate-secrets.sh > infra/k3s/20-secrets.yaml
|
||||||
|
# DOCKER_HOST_ADDRESS in 60-jvb.yaml auf die Public-IP von darkember setzen
|
||||||
|
kubectl apply -f infra/k3s/20-secrets.yaml
|
||||||
|
```
|
||||||
|
4. **Gitea-Repo + Secret KUBECONFIG_B64**: Repo bei Gitea anlegen, KUBECONFIG_B64 als Repo-Secret hinterlegen (gleicher Wert wie bei Embertime), push.
|
||||||
|
|
||||||
|
Danach: Pipeline rollt aus, in ~3 Min steht `https://meet.it.financeflow.de`.
|
||||||
|
|
||||||
|
## Was NICHT machen
|
||||||
|
|
||||||
|
- Keine Authentifizierung aktivieren — der Witz ist, dass der Service ohne Login funktioniert. `ENABLE_AUTH=0` ist Pflicht.
|
||||||
|
- Keinen Jibri (Recording) ohne expliziten Auftrag — braucht extra Pod mit Chrome + viel mehr Ressourcen
|
||||||
|
- Kein Helm — bleibt beim raw-Manifest-Pattern wie Embertime
|
||||||
|
- Nicht `replicas > 1` für prosody/jicofo — beide sind stateful Single-Instance
|
||||||
|
- JVB skaliert prinzipiell horizontal, aber für ein Single-Cluster reicht 1 Replica
|
||||||
|
|
||||||
|
## Verwandt im Obsidian-Vault
|
||||||
|
|
||||||
|
- `feedback_git_workflow.md` — Klone-Pfad, Gitea-SSH-Setup
|
||||||
|
- Embertime-CLAUDE.md (`~/Developer/embertime/CLAUDE.md`) — gleicher Deploy-Pattern, gleiches KUBECONFIG-Secret
|
||||||
4
infra/k3s/00-namespace.yaml
Normal file
4
infra/k3s/00-namespace.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: jitsi
|
||||||
46
infra/k3s/10-config.yaml
Normal file
46
infra/k3s/10-config.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Non-sensitive env shared across all jitsi components. Sensitive values
|
||||||
|
# (XMPP component passwords) live in the 20-secrets.yaml that is NOT
|
||||||
|
# committed to git — see scripts/generate-secrets.sh.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: jitsi-config
|
||||||
|
namespace: jitsi
|
||||||
|
data:
|
||||||
|
# === Public-facing config ===
|
||||||
|
PUBLIC_URL: "https://meet.it.financeflow.de"
|
||||||
|
TZ: "Europe/Berlin"
|
||||||
|
|
||||||
|
# === XMPP topology (internal hostnames — do not change without
|
||||||
|
# updating all 4 components in lockstep) ===
|
||||||
|
XMPP_DOMAIN: "meet.jitsi"
|
||||||
|
XMPP_AUTH_DOMAIN: "auth.meet.jitsi"
|
||||||
|
XMPP_INTERNAL_MUC_DOMAIN: "internal-muc.meet.jitsi"
|
||||||
|
XMPP_MUC_DOMAIN: "muc.meet.jitsi"
|
||||||
|
XMPP_GUEST_DOMAIN: "guest.meet.jitsi"
|
||||||
|
XMPP_RECORDER_DOMAIN: "recorder.meet.jitsi"
|
||||||
|
XMPP_SERVER: "prosody.jitsi.svc.cluster.local"
|
||||||
|
XMPP_BOSH_URL_BASE: "http://prosody.jitsi.svc.cluster.local:5280"
|
||||||
|
|
||||||
|
# === Auth disabled — anyone with the URL can start a room. That's the
|
||||||
|
# whole point of self-hosting (avoids the meet.jit.si Google/GitHub
|
||||||
|
# moderator gate). ===
|
||||||
|
ENABLE_AUTH: "0"
|
||||||
|
ENABLE_GUESTS: "0"
|
||||||
|
|
||||||
|
# === TLS handled by ingress cert-manager, not by the jitsi/web container ===
|
||||||
|
ENABLE_LETSENCRYPT: "0"
|
||||||
|
ENABLE_HTTP_REDIRECT: "0"
|
||||||
|
DISABLE_HTTPS: "1"
|
||||||
|
|
||||||
|
# === Videobridge brewery (where jicofo finds JVBs over XMPP) ===
|
||||||
|
JVB_BREWERY_MUC: "jvbbrewery"
|
||||||
|
|
||||||
|
# === STUN — default Jitsi-hosted STUN servers; ok for getting started ===
|
||||||
|
JVB_STUN_SERVERS: "meet-jit-si-turnrelay.jitsi.net:443"
|
||||||
|
|
||||||
|
# === Minor UX tweaks ===
|
||||||
|
ENABLE_PREJOIN_PAGE: "1"
|
||||||
|
ENABLE_WELCOME_PAGE: "1"
|
||||||
|
ENABLE_TRANSCRIPTIONS: "0"
|
||||||
|
ENABLE_RECORDING: "0"
|
||||||
20
infra/k3s/20-secrets.yaml.example
Normal file
20
infra/k3s/20-secrets.yaml.example
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# TEMPLATE — do NOT commit a filled-in copy. Generate the real secret
|
||||||
|
# via scripts/generate-secrets.sh and apply once out-of-band:
|
||||||
|
#
|
||||||
|
# ./scripts/generate-secrets.sh > infra/k3s/20-secrets.yaml
|
||||||
|
# kubectl apply -f infra/k3s/20-secrets.yaml
|
||||||
|
#
|
||||||
|
# Component passwords are only used cluster-internally between
|
||||||
|
# prosody/jicofo/jvb — clients (browsers) never see them.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: jitsi-secrets
|
||||||
|
namespace: jitsi
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
JICOFO_COMPONENT_SECRET: "REPLACE_WITH_32_RANDOM_CHARS"
|
||||||
|
JICOFO_AUTH_USER: "focus"
|
||||||
|
JICOFO_AUTH_PASSWORD: "REPLACE_WITH_32_RANDOM_CHARS"
|
||||||
|
JVB_AUTH_USER: "jvb"
|
||||||
|
JVB_AUTH_PASSWORD: "REPLACE_WITH_32_RANDOM_CHARS"
|
||||||
47
infra/k3s/30-prosody.yaml
Normal file
47
infra/k3s/30-prosody.yaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# XMPP server — cluster-internal only. Holds the conference state and
|
||||||
|
# brokers messages between web (client) ↔ jicofo ↔ jvb. Single-replica
|
||||||
|
# stateful service; do NOT scale.
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: prosody
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels: { app: prosody }
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: { app: prosody }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: prosody
|
||||||
|
image: jitsi/prosody:stable
|
||||||
|
envFrom:
|
||||||
|
- configMapRef: { name: jitsi-config }
|
||||||
|
- secretRef: { name: jitsi-secrets }
|
||||||
|
ports:
|
||||||
|
- { name: c2s, containerPort: 5222 }
|
||||||
|
- { name: comp, containerPort: 5347 }
|
||||||
|
- { name: bosh, containerPort: 5280 }
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket: { port: 5222 }
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
resources:
|
||||||
|
requests: { cpu: 50m, memory: 128Mi }
|
||||||
|
limits: { cpu: 500m, memory: 512Mi }
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: prosody
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
selector: { app: prosody }
|
||||||
|
ports:
|
||||||
|
- { name: c2s, port: 5222, targetPort: 5222 }
|
||||||
|
- { name: comp, port: 5347, targetPort: 5347 }
|
||||||
|
- { name: bosh, port: 5280, targetPort: 5280 }
|
||||||
26
infra/k3s/40-jicofo.yaml
Normal file
26
infra/k3s/40-jicofo.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Focus/conference manager. Talks to prosody as a component, signs
|
||||||
|
# users into rooms, picks JVBs from the brewery for video routing.
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: jicofo
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels: { app: jicofo }
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: { app: jicofo }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: jicofo
|
||||||
|
image: jitsi/jicofo:stable
|
||||||
|
envFrom:
|
||||||
|
- configMapRef: { name: jitsi-config }
|
||||||
|
- secretRef: { name: jitsi-secrets }
|
||||||
|
resources:
|
||||||
|
requests: { cpu: 50m, memory: 256Mi }
|
||||||
|
limits: { cpu: 500m, memory: 1Gi }
|
||||||
40
infra/k3s/50-web.yaml
Normal file
40
infra/k3s/50-web.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Static Meet UI + nginx that proxies XMPP-over-BOSH back to prosody.
|
||||||
|
# Exposed via Ingress in 70-ingress.yaml.
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: jitsi-web
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels: { app: jitsi-web }
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: { app: jitsi-web }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: web
|
||||||
|
image: jitsi/web:stable
|
||||||
|
envFrom:
|
||||||
|
- configMapRef: { name: jitsi-config }
|
||||||
|
- secretRef: { name: jitsi-secrets }
|
||||||
|
ports:
|
||||||
|
- { name: http, containerPort: 80 }
|
||||||
|
readinessProbe:
|
||||||
|
httpGet: { path: /, port: 80 }
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
resources:
|
||||||
|
requests: { cpu: 50m, memory: 128Mi }
|
||||||
|
limits: { cpu: 500m, memory: 512Mi }
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: jitsi-web
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
selector: { app: jitsi-web }
|
||||||
|
ports:
|
||||||
|
- { name: http, port: 80, targetPort: 80 }
|
||||||
47
infra/k3s/60-jvb.yaml
Normal file
47
infra/k3s/60-jvb.yaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Videobridge — routes the actual media streams. Two critical bits:
|
||||||
|
#
|
||||||
|
# 1) hostNetwork: true — JVB binds UDP 10000 directly on the node's
|
||||||
|
# external interface. The router/firewall must forward UDP 10000
|
||||||
|
# from the public IP to that node, otherwise browsers can't reach
|
||||||
|
# it and you get audio-only fallback.
|
||||||
|
#
|
||||||
|
# 2) DOCKER_HOST_ADDRESS — the public IP/hostname browsers will use
|
||||||
|
# to reach the bridge. Replace `__PUBLIC_IP__` with darkember's
|
||||||
|
# public IP before applying, or override via kustomize/sed in the
|
||||||
|
# deploy step.
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: jvb
|
||||||
|
namespace: jitsi
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels: { app: jvb }
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: { app: jvb }
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
dnsPolicy: ClusterFirstWithHostNet
|
||||||
|
containers:
|
||||||
|
- name: jvb
|
||||||
|
image: jitsi/jvb:stable
|
||||||
|
envFrom:
|
||||||
|
- configMapRef: { name: jitsi-config }
|
||||||
|
- secretRef: { name: jitsi-secrets }
|
||||||
|
env:
|
||||||
|
- name: DOCKER_HOST_ADDRESS
|
||||||
|
value: "__PUBLIC_IP__"
|
||||||
|
- name: JVB_PORT
|
||||||
|
value: "10000"
|
||||||
|
ports:
|
||||||
|
- name: media
|
||||||
|
containerPort: 10000
|
||||||
|
hostPort: 10000
|
||||||
|
protocol: UDP
|
||||||
|
resources:
|
||||||
|
requests: { cpu: 100m, memory: 256Mi }
|
||||||
|
limits: { cpu: 2, memory: 2Gi }
|
||||||
30
infra/k3s/70-ingress.yaml
Normal file
30
infra/k3s/70-ingress.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# TLS termination via cert-manager — same `letsencrypt-prod` ClusterIssuer
|
||||||
|
# as embertime/gitea. Traffic forwarded to jitsi-web on :80. JVB media
|
||||||
|
# (UDP 10000) goes around the ingress entirely (hostNetwork on the node).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: jitsi
|
||||||
|
namespace: jitsi
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- meet.it.financeflow.de
|
||||||
|
secretName: jitsi-tls
|
||||||
|
rules:
|
||||||
|
- host: meet.it.financeflow.de
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: jitsi-web
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
34
scripts/generate-secrets.sh
Executable file
34
scripts/generate-secrets.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Generates a 20-secrets.yaml with fresh random component passwords.
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/generate-secrets.sh > infra/k3s/20-secrets.yaml
|
||||||
|
# kubectl apply -f infra/k3s/20-secrets.yaml
|
||||||
|
#
|
||||||
|
# Re-running rotates the passwords — every component then needs to be
|
||||||
|
# restarted (kubectl rollout restart) so they pick up the new env.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# 24 random bytes → 32 base64 chars, stripped of slashes/+ for safety in
|
||||||
|
# env vars + URLs. Avoids the SIGPIPE issue with `tr | head` under
|
||||||
|
# pipefail.
|
||||||
|
rand() { openssl rand -hex 16; } # 32 hex chars = 16 bytes entropy, plenty for component auth
|
||||||
|
|
||||||
|
JICOFO_COMPONENT_SECRET=$(rand)
|
||||||
|
JICOFO_AUTH_PASSWORD=$(rand)
|
||||||
|
JVB_AUTH_PASSWORD=$(rand)
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: jitsi-secrets
|
||||||
|
namespace: jitsi
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
JICOFO_COMPONENT_SECRET: "${JICOFO_COMPONENT_SECRET}"
|
||||||
|
JICOFO_AUTH_USER: "focus"
|
||||||
|
JICOFO_AUTH_PASSWORD: "${JICOFO_AUTH_PASSWORD}"
|
||||||
|
JVB_AUTH_USER: "jvb"
|
||||||
|
JVB_AUTH_PASSWORD: "${JVB_AUTH_PASSWORD}"
|
||||||
|
EOF
|
||||||
Loading…
Reference in New Issue
Block a user