Mediamtx + repertory instance

This commit is contained in:
Ian Keane 2026-09-14 13:37:00 -04:00
parent 39420f524b
commit a0b28b7a01
13 changed files with 470 additions and 2 deletions

View file

@ -0,0 +1,5 @@
apiVersion: v2
name: mediamtx
description: MediaMTX streaming server + zoitestream landing page/API for stream.dumpnet.chat
type: application
version: 0.1.0

View file

@ -0,0 +1,69 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mediamtx-config
namespace: mediamtx
data:
mediamtx.yml: |
logLevel: info
authMethod: internal
authInternalUsers:
- user: {{ .Values.publishUser }}
pass: __PUBLISH_PASSWORD__
ips: []
permissions:
- action: publish
path: ""
- action: read
path: ""
- action: playback
path: ""
- user: any
pass: ""
ips: []
permissions:
- action: read
path: ""
- action: playback
path: ""
rtmp: true
rtmpAddress: :{{ .Values.mediamtx.rtmpPort }}
rtmpEncryption: "no"
hls: true
hlsAddress: :8888
hlsVariant: lowLatency
hlsAllowOrigin: "*"
hlsSegmentCount: 7
hlsSegmentDuration: 1s
hlsPartDuration: 200ms
webrtc: true
webrtcAddress: :{{ .Values.mediamtx.webrtcHttpPort }}
webrtcEncryption: false
webrtcAllowOrigin: "*"
webrtcLocalUDPAddress: :{{ .Values.mediamtx.webrtcUdpPort }}
webrtcAdditionalHosts:
- {{ .Values.publicIp }}
webrtcICEServers2:
- url: stun:stun.l.google.com:19302
- url: stun:stun1.l.google.com:19302
rtsp: false
srt: false
pathDefaults:
source: publisher
runOnReady: >
wget -q -O- --post-data "path=$MTX_PATH&source_type=$MTX_SOURCE_TYPE"
"http://localhost:5000/hooks/ready?token=$HOOK_TOKEN"
runOnReadyRestart: false
runOnNotReady: >
wget -q -O- --post-data "path=$MTX_PATH"
"http://localhost:5000/hooks/not-ready?token=$HOOK_TOKEN"
runOnNotReadyRestart: false
paths:
all_others: {}

View file

@ -0,0 +1,27 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: zoitestream-secrets
namespace: mediamtx
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: zoitestream-secrets
data:
- secretKey: PUBLISH_PASSWORD
remoteRef:
key: dumpnet
property: mediamtx.publish_password
- secretKey: HOOK_TOKEN
remoteRef:
key: dumpnet
property: mediamtx.hook_token
- secretKey: CREDS_TOKEN
remoteRef:
key: dumpnet
property: mediamtx.creds_token

View file

@ -0,0 +1,125 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mediamtx
namespace: mediamtx
spec:
replicas: 1
selector:
matchLabels:
app: mediamtx
template:
metadata:
labels:
app: mediamtx
spec:
hostNetwork: true
imagePullSecrets:
- name: forgejo-registry
containers:
- name: mediamtx
image: {{ .Values.mediamtx.image }}
command: ["/bin/sh", "-c"]
args:
- |
sed "s|__PUBLISH_PASSWORD__|$PUBLISH_PASSWORD|g" /etc/mediamtx/mediamtx.yml > /tmp/mediamtx.yml
exec /mediamtx /tmp/mediamtx.yml
env:
- name: HOOK_TOKEN
valueFrom:
secretKeyRef:
name: zoitestream-secrets
key: HOOK_TOKEN
- name: PUBLISH_PASSWORD
valueFrom:
secretKeyRef:
name: zoitestream-secrets
key: PUBLISH_PASSWORD
ports:
- name: rtmp
containerPort: {{ .Values.mediamtx.rtmpPort }}
- name: webrtc-http
containerPort: {{ .Values.mediamtx.webrtcHttpPort }}
- name: webrtc-udp
containerPort: {{ .Values.mediamtx.webrtcUdpPort }}
protocol: UDP
volumeMounts:
- name: config
mountPath: /etc/mediamtx/mediamtx.yml
subPath: mediamtx.yml
- name: zoitestream
image: "{{ .Values.registry.host }}/{{ .Values.registry.user }}/zoitestream:latest"
env:
- name: DOMAIN
value: "stream.{{ .Values.domain }}"
- name: RTMP_PORT
value: "{{ .Values.mediamtx.rtmpPort }}"
- name: PUBLISH_USER
value: {{ .Values.publishUser }}
- name: STATE_DB_PATH
value: /data/zoitestream.db
envFrom:
- secretRef:
name: zoitestream-secrets
ports:
- name: http
containerPort: 5000
readinessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 3
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 10
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: config
configMap:
name: mediamtx-config
- name: data
hostPath:
path: /var/local/appdata/zoitestream
type: DirectoryOrCreate
---
# HTTP-only Service (landing page + API), routed through ingress-nginx
apiVersion: v1
kind: Service
metadata:
name: zoitestream
namespace: mediamtx
spec:
selector:
app: mediamtx
ports:
- port: 80
targetPort: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zoitestream
namespace: mediamtx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- stream.{{ .Values.domain }}
secretName: zoitestream-tls
rules:
- host: stream.{{ .Values.domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zoitestream
port:
number: 80

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Namespace
metadata:
name: mediamtx
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged

View file

@ -0,0 +1,27 @@
{{- $host := .Values.registry.host }}
{{- $user := .Values.registry.user }}
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: forgejo-registry
namespace: mediamtx
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: forgejo-registry
template:
engineVersion: v2
mergePolicy: Replace
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: '{"auths":{"{{ $host }}":{"username":"{{ $user }}","password":"{{ "{{" }} .registry_token {{ "}}" }}","auth":"{{ "{{" }} printf "{{ $user }}:%s" .registry_token | b64enc {{ "}}" }}"}}}'
data:
- secretKey: registry_token
remoteRef:
key: dumpnet
property: forgejo.registry_token

View file

@ -0,0 +1,10 @@
domain: dumpnet.chat
registry:
host: forge.keane.sh
user: ian
mediamtx:
image: bluenviron/mediamtx:latest-ffmpeg
rtmpPort: 1935
webrtcHttpPort: 8889
webrtcUdpPort: 8189
publishUser: streamer

View file

@ -2,4 +2,4 @@ domain: dumpnet.chat
registry:
host: forge.keane.sh
user: ian
corsOrigins: "*"
corsOrigins: "https://repertory.dumpnet.chat"