diff --git a/.goosehints b/.goosehints index 01cc646..9757550 100644 --- a/.goosehints +++ b/.goosehints @@ -129,7 +129,14 @@ before improvising a new pattern. centralized services." - `registry.host` / `registry.user` are values in the root `values.yaml` — reference them, don't hardcode `forge.keane.sh`/`ian` in new charts. - +- For any service whose image you personally build/push (e.g. `zoitestream`, + `mcp-auth-proxy`, `repertory-api`) — as opposed to an official upstream + image — set `imagePullPolicy: Always` on that container. These use + floating `:latest` tags with no digest pinning, and this is a single-node + cluster where Kubernetes will otherwise happily reuse a stale cached + image after you push a new one, requiring a manual `kubectl delete pod` + to force a repull. `imagePullPolicy: Always` makes every pod + restart/reschedule actually check the registry. ## Databases - One shared Postgres in the `data` group/namespace (`postgres`), used by @@ -199,3 +206,12 @@ before improvising a new pattern. day-to-day ops, Makefile reference, forking/multi-environment notes. If a new operational gotcha is discovered (like the two-phase apply, or `make clean`), add it to the README, not just this file. + +## Git + +- **Never run `git commit` or `git push`** (in this repo, `zoitestream`, + `repertory`, `repertory-api`, or any other repo) unless the user + explicitly asks for it in that specific message. Staging/diffing is + fine; committing/pushing is the user's call, always. This applies even + after making a series of edits the user clearly wants kept — stop and + let them commit. diff --git a/Makefile b/Makefile index 33058f2..b4891ff 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: init plan apply destroy clean kubeconfig talosconfig argocd-password bootstrap decrypt post-apply build-mcp-auth-proxy +.PHONY: init plan apply destroy clean kubeconfig talosconfig argocd-password bootstrap decrypt post-apply build-mcp-auth-proxy stream-url SECRET ?= dumpnet FORGEJO_REGISTRY ?= forge.keane.sh @@ -79,6 +79,16 @@ argocd-password: --query SecretString --output text | python3 -c \ "import sys,json; print(json.load(sys.stdin)['cluster']['argocd_admin_password'])" +# Build the current RTMP publish URL from the dumpnet secret (mediamtx.*) +# — handy for testing without going through the IRC bot, since the +# zoitestream API is cluster-internal only. +stream-url: + @aws secretsmanager get-secret-value --secret-id $(SECRET) \ + --query SecretString --output text | python3 -c \ + "import sys, json; \ + d = json.load(sys.stdin)['mediamtx']; \ + print(f\"rtmp://stream.dumpnet.chat:1935/live?user=streamer&pass={d['publish_password']}\")" + # Decrypt sensitive files to /tmp for one-off talosctl use # Files are never decrypted in the repo directory decrypt: diff --git a/charts/mcp-auth-proxy/templates/mcp-auth-proxy-git.yaml b/charts/mcp-auth-proxy/templates/mcp-auth-proxy-git.yaml index ea00f66..13c7f23 100644 --- a/charts/mcp-auth-proxy/templates/mcp-auth-proxy-git.yaml +++ b/charts/mcp-auth-proxy/templates/mcp-auth-proxy-git.yaml @@ -18,6 +18,7 @@ spec: containers: - name: mcp-auth-proxy image: {{ .Values.registry.host }}/{{ .Values.registry.user }}/mcp-auth-proxy:latest + imagePullPolicy: Always args: - --external-url=https://git-mcp-oauth.dumpnet.chat - --no-auto-tls=true diff --git a/charts/mediamtx/templates/mediamtx.yaml b/charts/mediamtx/templates/mediamtx.yaml index 63eb27d..180d7df 100644 --- a/charts/mediamtx/templates/mediamtx.yaml +++ b/charts/mediamtx/templates/mediamtx.yaml @@ -49,6 +49,7 @@ spec: subPath: mediamtx.yml - name: zoitestream image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/zoitestream:latest" + imagePullPolicy: Always env: - name: DOMAIN value: "stream.{{ .Values.domain }}" @@ -99,6 +100,20 @@ spec: - port: 80 targetPort: 5000 --- +# HLS Service — MediaMTX's HTTP HLS server, for browser playback and +# direct mpv/ffmpeg consumption of the raw .m3u8 playlist. +apiVersion: v1 +kind: Service +metadata: + name: mediamtx-hls + namespace: mediamtx +spec: + selector: + app: mediamtx + ports: + - port: 8888 + targetPort: 8888 +--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -116,10 +131,38 @@ spec: - host: stream.{{ .Values.domain }} http: paths: - - path: / + - path: /api pathType: Prefix backend: service: name: zoitestream port: number: 80 + - path: /hooks + pathType: Prefix + backend: + service: + name: zoitestream + port: + number: 80 + - path: /health + pathType: Exact + backend: + service: + name: zoitestream + port: + number: 80 + - path: / + pathType: Exact + backend: + service: + name: zoitestream + port: + number: 80 + - path: / + pathType: Prefix + backend: + service: + name: mediamtx-hls + port: + number: 8888 diff --git a/charts/repertory-api/templates/repertory-api.yaml b/charts/repertory-api/templates/repertory-api.yaml index fec3b4e..5790610 100644 --- a/charts/repertory-api/templates/repertory-api.yaml +++ b/charts/repertory-api/templates/repertory-api.yaml @@ -18,6 +18,7 @@ spec: containers: - name: repertory-api image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest" + imagePullPolicy: Always ports: - containerPort: 5000 envFrom: @@ -90,6 +91,7 @@ spec: containers: - name: migrate image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest" + imagePullPolicy: Always command: ["uv", "run", "alembic", "upgrade", "head"] envFrom: - secretRef: