Compare commits

..

3 commits

5 changed files with 75 additions and 3 deletions

View file

@ -129,7 +129,14 @@ before improvising a new pattern.
centralized services." centralized services."
- `registry.host` / `registry.user` are values in the root `values.yaml` — - `registry.host` / `registry.user` are values in the root `values.yaml` —
reference them, don't hardcode `forge.keane.sh`/`ian` in new charts. 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 ## Databases
- One shared Postgres in the `data` group/namespace (`postgres`), used by - 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 day-to-day ops, Makefile reference, forking/multi-environment notes. If a
new operational gotcha is discovered (like the two-phase apply, or new operational gotcha is discovered (like the two-phase apply, or
`make clean`), add it to the README, not just this file. `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.

View file

@ -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 SECRET ?= dumpnet
FORGEJO_REGISTRY ?= forge.keane.sh FORGEJO_REGISTRY ?= forge.keane.sh
@ -79,6 +79,16 @@ argocd-password:
--query SecretString --output text | python3 -c \ --query SecretString --output text | python3 -c \
"import sys,json; print(json.load(sys.stdin)['cluster']['argocd_admin_password'])" "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 # Decrypt sensitive files to /tmp for one-off talosctl use
# Files are never decrypted in the repo directory # Files are never decrypted in the repo directory
decrypt: decrypt:

View file

@ -18,6 +18,7 @@ spec:
containers: containers:
- name: mcp-auth-proxy - name: mcp-auth-proxy
image: {{ .Values.registry.host }}/{{ .Values.registry.user }}/mcp-auth-proxy:latest image: {{ .Values.registry.host }}/{{ .Values.registry.user }}/mcp-auth-proxy:latest
imagePullPolicy: Always
args: args:
- --external-url=https://git-mcp-oauth.dumpnet.chat - --external-url=https://git-mcp-oauth.dumpnet.chat
- --no-auto-tls=true - --no-auto-tls=true

View file

@ -49,6 +49,7 @@ spec:
subPath: mediamtx.yml subPath: mediamtx.yml
- name: zoitestream - name: zoitestream
image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/zoitestream:latest" image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/zoitestream:latest"
imagePullPolicy: Always
env: env:
- name: DOMAIN - name: DOMAIN
value: "stream.{{ .Values.domain }}" value: "stream.{{ .Values.domain }}"
@ -99,6 +100,20 @@ spec:
- port: 80 - port: 80
targetPort: 5000 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 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
@ -116,10 +131,38 @@ spec:
- host: stream.{{ .Values.domain }} - host: stream.{{ .Values.domain }}
http: http:
paths: paths:
- path: / - path: /api
pathType: Prefix pathType: Prefix
backend: backend:
service: service:
name: zoitestream name: zoitestream
port: port:
number: 80 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

View file

@ -18,6 +18,7 @@ spec:
containers: containers:
- name: repertory-api - name: repertory-api
image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest" image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest"
imagePullPolicy: Always
ports: ports:
- containerPort: 5000 - containerPort: 5000
envFrom: envFrom:
@ -90,6 +91,7 @@ spec:
containers: containers:
- name: migrate - name: migrate
image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest" image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/repertory-api:latest"
imagePullPolicy: Always
command: ["uv", "run", "alembic", "upgrade", "head"] command: ["uv", "run", "alembic", "upgrade", "head"]
envFrom: envFrom:
- secretRef: - secretRef: