Compare commits

..

10 commits

Author SHA1 Message Date
Astra Logical
2d994c5157 Bump sonarr-anime pvc. Update forgejo to enable ssh server 2026-07-21 16:25:32 -04:00
Astra Logical
b8d48da235 Stub out semaphore. Set up forgejo 2026-07-21 14:59:02 -04:00
Astra Logical
40edb4cf47 Auto-Upgrade services with keel. Clean up kompose junk. Break out pvcs from deployments 2026-07-21 11:21:26 -04:00
Astra Logical
e3d1bcde17 Bump slskd pvc 2026-07-19 10:45:10 -04:00
Astra Logical
1594d6721d Musicseerr -> DroppedNeedle and cleanup of retired services 2026-07-18 17:41:29 -04:00
Astra Logical
7941c5645c Stub out OSM support 2026-06-28 10:59:26 -04:00
KnightArtorias
ff3eda5333 Transition to synapse 2026-06-22 18:48:26 -04:00
KnightArtorias
e5ce3fb63a Intial working matrix config 2026-06-21 18:01:24 -04:00
KnightArtorias
ba3ca3503f Start some matrix stuff 2026-06-20 21:49:26 -04:00
KnightArtorias
faacf921af Use shelfmark instead of RMAB 2026-06-20 21:17:01 -04:00
120 changed files with 2736 additions and 595 deletions

View file

@ -14,4 +14,4 @@ spec:
volumes:
- name: target-volume
persistentVolumeClaim:
claimName: musicseerr-config-pvc
claimName: calibre-web-config-pvc

72
keel/keel.yaml Normal file
View file

@ -0,0 +1,72 @@
apiVersion: v1
kind: Namespace
metadata:
name: keel
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: keel
namespace: keel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: keel
rules:
- apiGroups: ["", "apps", "batch", "extensions"]
resources:
- namespaces
- deployments
- daemonsets
- statefulsets
- cronjobs
- pods
- replicationcontrollers
verbs: ["get", "list", "watch", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: keel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: keel
subjects:
- kind: ServiceAccount
name: keel
namespace: keel
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keel
namespace: keel
labels:
app: keel
spec:
replicas: 1
selector:
matchLabels:
app: keel
template:
metadata:
labels:
app: keel
spec:
serviceAccountName: keel
containers:
- name: keel
image: keelhq/keel:latest
imagePullPolicy: Always
env:
- name: POLL
value: "true"
- name: SCHEDULER_FREQUENCY
value: "1h"
- name: AUTO_UPDATE_EVERYTHING
value: "false"
ports:
- containerPort: 9300
name: keel

View file

@ -0,0 +1,255 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: synapse-config-tmpl
namespace: matrix
data:
homeserver.yaml: |
server_name: "starling.mynest.love"
public_baseurl: "https://starling.mynest.love"
media_store_path: "/data/media_store"
uploads_path: "/data/uploads"
serve_server_wellknown: true
serve_client_wellknown: true
extra_well_known_client_content:
"m.homeserver":
base_url: "https://starling.mynest.love"
"org.matrix.msc4143.rtc_foci":
- type: livekit
livekit_service_url: "https://matrix-rtc.mynest.love"
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: "${POSTGRES_USER}"
password: "${POSTGRES_PASSWORD}"
database: "synapse"
host: "postgres-svc"
cp_min: 5
cp_max: 10
oidc_providers:
- idp_id: keycloak
idp_name: "Nest SSO"
discover: true
issuer: "https://sso.mynest.love/realms/nest"
client_id: "${CLIENT_ID}"
client_secret: "${CLIENT_SECRET}"
scopes: ["openid", "profile", "email"]
user_mapping_provider:
config:
localpart_template: "{{ user.preferred_username }}"
display_name_template: "{{ user.name }}"
# MatrixRTC & LiveKit Requirements
experimental_features:
msc4140_enabled: true
msc4143_enabled: true
macaroon_secret_key: "${SYNAPSE_MACAROON_KEY}"
form_secret: "${SYNAPSE_REGISTRATION_SECRET}"
registration_shared_secret: "${SYNAPSE_REGISTRATION_SECRET}"
enable_registration: false
report_stats: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: matrix-secrets
key: POSTGRES_USER
- name: POSTGRES_DB
value: "synapse"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: POSTGRES_PASSWORD
- name: POSTGRES_INITDB_ARGS
value: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
subPath: synapse-data
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgres-data
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: synapse
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: synapse
template:
metadata:
labels:
app: synapse
spec:
initContainers:
- name: generate-config
image: alpine:latest
command: ["/bin/sh", "-c", "apk add gettext && envsubst < /tmpl/homeserver.yaml > /data/homeserver.yaml && chown -R 991:991 /data"]
envFrom:
- secretRef:
name: matrix-secrets
volumeMounts:
- name: config-tmpl
mountPath: /tmpl/homeserver.yaml
subPath: homeserver.yaml
- name: synapse-data
mountPath: /data
containers:
- name: synapse
image: matrixdotorg/synapse:latest
ports:
- containerPort: 8008
env:
- name: SYNAPSE_CONFIG_PATH
value: "/data/homeserver.yaml"
volumeMounts:
- name: synapse-data
mountPath: /data
volumes:
- name: synapse-data
persistentVolumeClaim:
claimName: synapse-data
- name: config-tmpl
configMap:
name: synapse-config-tmpl
---
apiVersion: v1
kind: ConfigMap
metadata:
name: livekit-config
namespace: matrix
data:
livekit.yaml: |
port: 7880
rtc:
tcp_port: 7881
udp_port: 7882
use_external_ip: true
turn:
cert_file: ""
key_file: ""
tls_port: 0
udp_port: 3478
external_tls: false
# Crucial for Matrix integration: Only the JWT service can create rooms
room:
auto_create: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: livekit
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: livekit
template:
metadata:
labels:
app: livekit
spec:
containers:
- name: livekit
image: livekit/livekit-server:latest
args: ["--config", "/etc/livekit.yaml"]
ports:
- containerPort: 7880
- containerPort: 7881
- containerPort: 7882
protocol: UDP
- containerPort: 3478
protocol: UDP
env:
- name: LK_KEY
valueFrom:
secretKeyRef:
name: matrix-secrets
key: LIVEKIT_KEY
- name: LK_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: LIVEKIT_SECRET
- name: LIVEKIT_KEYS
value: '$(LK_KEY): $(LK_SECRET)'
volumeMounts:
- name: config-volume
mountPath: /etc/livekit.yaml
subPath: livekit.yaml
volumes:
- name: config-volume
configMap:
name: livekit-config
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lk-jwt-service
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: lk-jwt-service
template:
metadata:
labels:
app: lk-jwt-service
spec:
containers:
- name: lk-jwt-service
image: ghcr.io/element-hq/lk-jwt-service:0.4.2
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: matrix-secrets
env:
- name: LIVEKIT_URL
value: "wss://matrix-rtc.mynest.love"
- name: LIVEKIT_FULL_ACCESS_HOMESERVERS
value: "starling.mynest.love"

View file

@ -0,0 +1,46 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: matrix-secrets
namespace: matrix
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: matrix-secrets
creationPolicy: Owner
data:
- secretKey: LIVEKIT_KEY
remoteRef:
key: matrix
property: livekit-key
- secretKey: LIVEKIT_SECRET
remoteRef:
key: matrix
property: livekit-secret
- secretKey: CLIENT_ID
remoteRef:
key: matrix
property: client-id
- secretKey: CLIENT_SECRET
remoteRef:
key: matrix
property: client-secret
- secretKey: POSTGRES_USER
remoteRef:
key: matrix
property: postgres-user
- secretKey: POSTGRES_PASSWORD
remoteRef:
key: matrix
property: postgres-password
- secretKey: SYNAPSE_MACAROON_KEY
remoteRef:
key: matrix
property: synapse-macaroon
- secretKey: SYNAPSE_REGISTRATION_SECRET
remoteRef:
key: matrix
property: synapse-registration

View file

@ -0,0 +1,67 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-ingress
namespace: matrix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- starling.mynest.love
secretName: matrix-tls
rules:
- host: starling.mynest.love
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: synapse-svc
port:
number: 8008
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-rtc-ingress
namespace: matrix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- matrix-rtc.mynest.love
secretName: matrix-rtc-tls
rules:
- host: matrix-rtc.mynest.love
http:
paths:
# 1. Route token generation traffic to the lk-jwt-service
- path: /sfu/get
pathType: Prefix
backend:
service:
name: lk-jwt-svc
port:
number: 8080
- path: /get_token
pathType: Prefix
backend:
service:
name: lk-jwt-svc
port:
number: 8080
# 2. Route all standard traffic and WebSockets to LiveKit
- path: /
pathType: Prefix
backend:
service:
name: livekit-svc
port:
number: 7880

View file

@ -0,0 +1,31 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: synapse-data
namespace: matrix
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: matrix
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: musicbrainz-db
spec:
replicas: 1
selector:
matchLabels:
app: musicbrainz-db
template:
metadata:
labels:
app: musicbrainz-db
spec:
nodeSelector:
kubernetes.io/hostname: robin
containers:
- name: postgres
image: postgres:16
envFrom:
- secretRef:
name: musicbrainz-secret
env:
- name: POSTGRES_DB
value: "musicbrainz_db"
ports:
- containerPort: 5432
volumeMounts:
- name: db-data
mountPath: /var/lib/postgresql/data
subPath: musicbrainz-data
volumes:
- name: db-data
persistentVolumeClaim:
claimName: musicbrainz-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: musicbrainz-redis
spec:
replicas: 1
selector:
matchLabels:
app: musicbrainz-redis
template:
metadata:
labels:
app: musicbrainz-redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: musicbrainz-web
spec:
replicas: 1
selector:
matchLabels:
app: musicbrainz-web
template:
metadata:
labels:
app: musicbrainz-web
spec:
containers:
- name: musicbrainz
image: metabrainz/musicbrainz-server:latest
ports:
- containerPort: 5000
envFrom:
- secretRef:
name: musicbrainz-secret
env:
- name: POSTGRES_HOST
value: "musicbrainz-db"
- name: REDIS_HOST
value: "musicbrainz-redis"
- name: MUSICBRAINZ_STANDALONE_SERVER
value: "1"

View file

@ -0,0 +1,26 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: musicbrainz-secret
namespace: default
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: musicbrainz-secret
creationPolicy: Owner
data:
- secretKey: BRAINZCODE
remoteRef:
key: musicbrainz
property: brainzcode
- secretKey: POSTGRES_USER
remoteRef:
key: musicbrainz
property: db-user
- secretKey: POSTGRES_PASSWORD
remoteRef:
key: musicbrainz
property: db-pass

View file

@ -0,0 +1,33 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: musicbrainz-raid-pv
spec:
capacity:
storage: 200Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-raid
local:
path: /mnt/raid/yarr/musicbrainz/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- robin
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: musicbrainz-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-raid
resources:
requests:
storage: 200Gi

View file

@ -0,0 +1,32 @@
apiVersion: v1
kind: Service
metadata:
name: musicbrainz-service
spec:
selector:
app: musicbrainz
ports:
- protocol: TCP
port: 5000
targetPort: 5000
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: musicbrainz-redis
spec:
selector:
app: musicbrainz-redis
ports:
- port: 6379
---
apiVersion: v1
kind: Service
metadata:
name: musicbrainz-db
spec:
selector:
app: musicbrainz-db
ports:
- port: 5432

View file

@ -0,0 +1,177 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: oauth2-proxy
name: oauth2-proxy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
ports:
- containerPort: 4180
protocol: TCP
name: proxy-port
env:
- name: OAUTH2_PROXY_PROVIDER
value: "keycloak-oidc"
- name: OAUTH2_PROXY_PROVIDER_DISPLAY_NAME
value: "Keycloak"
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: navigation-secrets
key: OIDC_CLIENT_ID
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: navigation-secrets
key: OIDC_CLIENT_SECRET
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: navigation-secrets
key: OAUTH2_PROXY_COOKIE_SECRET
- name: OAUTH2_PROXY_UPSTREAMS
value: "file:///dev/null"
- name: OAUTH2_PROXY_HTTP_ADDRESS
value: "0.0.0.0:4180"
- name: OAUTH2_PROXY_REDIRECT_URL
value: "https://migrate.mynest.love/oauth2/callback"
- name: OAUTH2_PROXY_OIDC_ISSUER_URL
value: "https://sso.mynest.love/realms/nest"
- name: OAUTH2_PROXY_COOKIE_DOMAINS
value: "migrate.mynest.love"
- name: OAUTH2_PROXY_WHITELIST_DOMAINS
value: "migrate.mynest.love"
- name: OAUTH2_PROXY_COOKIE_SECURE
value: "true"
- name: OAUTH2_PROXY_EMAIL_DOMAINS
value: "*"
- name: OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS
value: "true"
- name: OAUTH2_PROXY_EXTRA_JWT_ISSUERS
value: "https://sso.mynest.love/realms/nest=account"
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: valhalla
name: valhalla
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: valhalla
strategy:
type: Recreate
template:
metadata:
labels:
app: valhalla
spec:
containers:
- name: valhalla
image: ghcr.io/valhalla/valhalla:latest
ports:
- containerPort: 8002
protocol: TCP
name: valhalla-port
env:
- name: TZ
value: America/New_York
- name: tile_urls
value: "https://download.geofabrik.de/north-america/us/maryland-latest.osm.pbf"
- name: build_elevation
value: "True"
- name: serve_tiles
value: "True"
- name: force_rebuild
value: "False"
volumeMounts:
- mountPath: /custom_files
name: valhalla-storage
volumes:
- name: valhalla-storage
persistentVolumeClaim:
claimName: valhalla-data-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: tileserver
name: tileserver
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: tileserver
strategy:
type: Recreate
template:
metadata:
labels:
app: tileserver
spec:
containers:
- name: tileserver
image: maptiler/tileserver-gl:latest
ports:
- containerPort: 8080
protocol: TCP
name: tileserver-port
volumeMounts:
- mountPath: /data
name: tileserver-storage
volumes:
- name: tileserver-storage
persistentVolumeClaim:
claimName: tileserver-data-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: photon
name: photon
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: photon
strategy:
type: Recreate
template:
metadata:
labels:
app: photon
spec:
containers:
- name: photon
image: komoot/photon:latest
ports:
- containerPort: 2322
protocol: TCP
name: photon-port
volumeMounts:
- mountPath: /photon/photon_data
name: photon-storage
volumes:
- name: photon-storage
persistentVolumeClaim:
claimName: photon-data-pvc

View file

@ -0,0 +1,26 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: navigation-secrets
namespace: default
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: navigation-secrets
creationPolicy: Owner
data:
- secretKey: OIDC_CLIENT_ID
remoteRef:
key: navigation
property: client-id
- secretKey: OIDC_CLIENT_SECRET
remoteRef:
key: navigation
property: client-secret
- secretKey: OAUTH2_PROXY_COOKIE_SECRET
remoteRef:
key: navigation
property: cookie-secret

View file

@ -0,0 +1,82 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: navigation-forwardauth
namespace: default
spec:
forwardAuth:
address: http://oauth2-proxy.default.svc.cluster.local:4180
trustForwardHeader: true
authResponseHeaders:
- "X-Auth-User"
- "X-Auth-Email"
- "Authorization"
---
# Unauthenticated Ingress for the OAuth Callback endpoint
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: navigation-ingress-oauth
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- migrate.mynest.love
secretName: navigation-tls
rules:
- host: migrate.mynest.love
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy
port:
name: http-proxy
---
# Authenticated Ingress protecting the mapping services
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: navigation-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.middlewares: default-navigation-forwardauth@kubernetescrd
spec:
tls:
- hosts:
- migrate.mynest.love
secretName: navigation-tls
rules:
- host: migrate.mynest.love
http:
paths:
- path: /route
pathType: Prefix
backend:
service:
name: valhalla
port:
name: http-valhalla
- path: /api
pathType: Prefix
backend:
service:
name: photon
port:
name: http-photon
- path: /
pathType: Prefix
backend:
service:
name: tileserver
port:
name: http-tileserver

View file

@ -0,0 +1,47 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: valhalla-data-pvc
namespace: default
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 50Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tileserver-data-pvc
namespace: default
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: photon-data-pvc
namespace: default
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 20Gi

View file

@ -0,0 +1,63 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: oauth2-proxy
name: oauth2-proxy
namespace: default
spec:
type: ClusterIP
ports:
- name: http-proxy
port: 4180
targetPort: proxy-port
selector:
app: oauth2-proxy
---
apiVersion: v1
kind: Service
metadata:
labels:
app: valhalla
name: valhalla
namespace: default
spec:
type: ClusterIP
ports:
- name: http-valhalla
port: 8002
targetPort: valhalla-port
selector:
app: valhalla
---
apiVersion: v1
kind: Service
metadata:
labels:
app: tileserver
name: tileserver
namespace: default
spec:
type: ClusterIP
ports:
- name: http-tileserver
port: 8080
targetPort: tileserver-port
selector:
app: tileserver
---
apiVersion: v1
kind: Service
metadata:
labels:
app: photon
name: photon
namespace: default
spec:
type: ClusterIP
ports:
- name: http-photon
port: 2322
targetPort: photon-port
selector:
app: photon

View file

@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: semaphore
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
app: semaphore
template:
metadata:
labels:
app: semaphore
spec:
initContainers:
- name: fix-volume-permissions
image: busybox
command: ["sh", "-c", "chown -R 1001:1001 /etc/semaphore && chmod 775 /etc/semaphore"]
volumeMounts:
- name: semaphore-data
mountPath: /etc/semaphore
containers:
- name: semaphore
image: semaphoreui/semaphore:latest
ports:
- containerPort: 3000
envFrom:
- secretRef:
name: ansible-secret
env:
- name: SEMAPHORE_DB_DIALECT
value: sqlite
- name: SEMAPHORE_DB_PATH
value: /etc/semaphore/semaphore.sqlite
- name: SEMAPHORE_ADMIN
value: "admin"
volumeMounts:
- name: semaphore-data
mountPath: /etc/semaphore
volumes:
- name: semaphore-data
persistentVolumeClaim:
claimName: semaphore-pvc

View file

@ -0,0 +1,26 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: ansible-secret
namespace: default
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: ansible-secret
creationPolicy: Owner
data:
- secretKey: SEMAPHORE_ADMIN_PASSWORD
remoteRef:
key: ansible
property: admin-pass
- secretKey: SEMAPHORE_ADMIN_NAME
remoteRef:
key: ansible
property: admin-user
- secretKey: SEMAPHORE_ADMIN_EMAIL
remoteRef:
key: ansible
property: admin-email

View file

@ -0,0 +1,17 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: semaphore-ingress
spec:
ingressClassName: traefik
rules:
- host: semaphore.k3s.home.nest
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: semaphore-svc
port:
number: 80

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: semaphore-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: semaphore-svc
spec:
ports:
- port: 80
targetPort: 3000
selector:
app: semaphore

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-abs.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: audiobookshelf
name: audiobookshelf
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: audiobookshelf
app: audiobookshelf
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-abs.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: audiobookshelf
app: audiobookshelf
spec:
containers:
- env:

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-abs.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: audiobookshelf
name: audiobookshelf
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: audiobookshelf
app: audiobookshelf

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr-anime
name: bazarr-anime
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: bazarr-anime
app: bazarr-anime
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr-anime
app: bazarr-anime
spec:
containers:
- env:
@ -50,18 +46,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/media
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-anime-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-anime-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr-anime
name: bazarr-anime
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: bazarr-anime
app: bazarr-anime

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr
name: bazarr
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: bazarr
app: bazarr
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr
app: bazarr
spec:
containers:
- env:
@ -50,18 +46,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/media
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 50Mi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: bazarr
name: bazarr
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: bazarr
app: bazarr

View file

@ -1,23 +1,22 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: calibre-web
name: calibre-web
annotations:
reloader.stakater.com/auto: "true"
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: calibre-web
app: calibre-web
strategy:
type: Recreate
template:
metadata:
labels:
io.kompose.service: calibre-web
app: calibre-web
spec:
containers:
- name: calibre-web

View file

@ -1,8 +1,6 @@
apiVersion: v1
kind: Service
metadata:
labels:
io.kompose.service: calibre-web
name: calibre-web
spec:
type: ClusterIP
@ -11,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: calibre-web
app: calibre-web

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: deluge
name: deluge
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: deluge
app: deluge
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: deluge
app: deluge
spec:
containers:
- env:
@ -61,18 +57,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/downloads
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: deluge-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 20Mi

View file

@ -1,7 +1,7 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyseerr-data-pvc
name: deluge-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: deluge
name: deluge
spec:
type: ClusterIP
@ -24,4 +19,4 @@ spec:
port: 82
targetPort: daemon
selector:
io.kompose.service: deluge
app: deluge

View file

@ -1,32 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: musicseerr
name: musicseerr
namespace: default
name: droppedneedle
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
app: musicseerr
app: droppedneedle
strategy:
type: Recreate
template:
metadata:
labels:
app: musicseerr
app: droppedneedle
spec:
containers:
- name: musicseerr
image: ghcr.io/habirabbu/musicseerr:latest
- name: droppedneedle
image: ghcr.io/habirabbu/droppedneedle:latest
ports:
- containerPort: 8688
protocol: TCP
name: web-ui
envFrom:
- secretRef:
name: musicseerr-secrets
env:
- name: PUID
value: "1000"
@ -40,24 +38,26 @@ spec:
value: "true"
- name: UVICORN_FORWARDED_ALLOW_IPS
value: "*"
- name: LIDARR_URL
value: "http://lidarr.k3s.home.nest"
- name: SLSKD_DOWNLOADS_PATH
value: "/yarr/downloads/slskd/complete"
volumeMounts:
- mountPath: /app/config
name: musicseerr-config
name: droppedneedle-config
- mountPath: /app/cache
name: musicseerr-cache
- mountPath: /music
name: droppedneedle-cache
- mountPath: /yarr
name: yarr
restartPolicy: Always
volumes:
- name: musicseerr-config
- name: droppedneedle-config
persistentVolumeClaim:
claimName: musicseerr-config-pvc
- name: musicseerr-cache
claimName: musicseerr-config-pvc # Service changed name, cannot rename PVC
- name: droppedneedle-cache
persistentVolumeClaim:
claimName: musicseerr-cache-pvc
# Note: in order for atomic renames to work we need the music library
# and the downloads folders to be on the same mount
- name: yarr
nfs:
server: robin.home.nest
path: /yarr/media
path: /yarr

View file

@ -1,7 +1,7 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: musicseerr-secrets
name: droppedneedle-secret
namespace: default
spec:
refreshInterval: "1h"
@ -9,10 +9,14 @@ spec:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: musicseerr-secrets
name: droppedneedle-secret
creationPolicy: Owner
data:
- secretKey: LIDARR_API_KEY
- secretKey: SERVICE_USER
remoteRef:
key: lidarr
property: api-key
key: dropped-needle
property: service-user
- secretKey: SERVICE_PASS
remoteRef:
key: dropped-needle
property: service-password

View file

@ -1,7 +1,7 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: musicseerr-ingress
name: droppedneedle-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
@ -12,7 +12,7 @@ spec:
tls:
- hosts:
- heron.mynest.love
secretName: musicseerr-tls
secretName: droppedneedle-tls
rules:
- host: heron.mynest.love
http:
@ -21,6 +21,6 @@ spec:
pathType: Prefix
backend:
service:
name: musicseerr
name: droppedneedle
port:
name: http-web

View file

@ -0,0 +1,66 @@
# Note: This service changed name from musicseerr to droppedneedle
# PVC names are immutable, so just keeping the old names
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: musicseerr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: musicseerr-cache-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 3Gi
---
# For use by the transcoding service
apiVersion: v1
kind: PersistentVolume
metadata:
name: droppedneedle-transcode-pv
spec:
capacity:
storage: 3Ti
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-raid
local:
path: /mnt/raid/yarr/media/music
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- robin
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: droppedneedle-transcode-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-raid
resources:
requests:
storage: 3Ti

View file

@ -2,8 +2,8 @@ apiVersion: v1
kind: Service
metadata:
labels:
app: musicseerr
name: musicseerr
app: droppedneedle
name: droppedneedle
namespace: default
spec:
type: ClusterIP
@ -12,4 +12,4 @@ spec:
port: 80
targetPort: web-ui
selector:
app: musicseerr
app: droppedneedle

View file

@ -0,0 +1,84 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: droppedneedle-transcoder-script
namespace: default
data:
transcode.sh: |
#!/bin/bash
WATCH_DIR="/music"
echo "Starting transcoder watch on $WATCH_DIR..."
inotifywait -m -r -e moved_to,close_write --format '%w%f' "$WATCH_DIR" | while read FILE
do
if [[ "${FILE,,}" == *.flac ]]; then
echo "Detected new FLAC via import: $FILE"
OPUS_FILE="${FILE%.*}.opus"
ffmpeg -y -i "$FILE" -acodec libopus -ac 2 -ab 160k "$OPUS_FILE"
if [ $? -eq 0 ]; then
echo "Transcode successful. Removing original FLAC..."
rm "$FILE"
echo "Triggering authenticated DroppedNeedle library scan..."
# 1. Authenticate and save the session cookie to a temporary jar
curl -s -X POST http://droppedneedle.default.svc.cluster.local:80/api/v1/auth/login \
-H "Content-Type: application/json" \
-d "{\"username\": \"$SERVICE_USER\", \"password\": \"$SERVICE_PASS\"}" \
-c /tmp/dn_cookies.txt
# 2. Trigger the scan using the saved session cookie
curl -s -X POST http://droppedneedle.default.svc.cluster.local:80/api/v1/library/scan/start \
-b /tmp/dn_cookies.txt
# 3. Clean up the cookie jar
rm /tmp/dn_cookies.txt
else
echo "Error: FFmpeg transcode failed for $FILE"
fi
fi
done
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: droppedneedle-transcoder
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
app: droppedneedle-transcoder
template:
metadata:
labels:
app: droppedneedle-transcoder
spec:
nodeSelector:
kubernetes.io/hostname: robin
containers:
- name: transcoder
image: alpine:latest
command: ["/bin/sh", "-c"]
args:
- "apk add --no-cache bash inotify-tools ffmpeg curl && bash /scripts/transcode.sh"
envFrom:
- secretRef:
name: droppedneedle-secret
volumeMounts:
- mountPath: /music
name: yarr
- mountPath: /scripts
name: script-volume
restartPolicy: Always
volumes:
- name: yarr
persistentVolumeClaim:
claimName: droppedneedle-transcode-pvc
- name: script-volume
configMap:
name: droppedneedle-transcoder-script

View file

@ -1,24 +1,20 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: flaresolverr
name: flaresolverr
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: flaresolverr
app: flaresolverr
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: flaresolverr
app: flaresolverr
spec:
containers:
- env:

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: flaresolverr
name: flaresolverr
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: flaresolverr
selector:
io.kompose.service: flaresolverr
app: flaresolverr

View file

@ -0,0 +1,139 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: forgejo
template:
metadata:
labels:
app: forgejo
spec:
containers:
- name: forgejo
image: codeberg.org/forgejo/forgejo:10
ports:
- containerPort: 3000
name: http
- containerPort: 2222
name: ssh
env:
# Core Application Config
- name: FORGEJO____APP_NAME
value: "Code Nest"
- name: FORGEJO__server__DOMAIN
value: "weaver.mynest.love"
- name: FORGEJO__server__ROOT_URL
value: "https://weaver.mynest.love/"
- name: FORGEJO__server__HTTP_PORT
value: "3000"
- name: FORGEJO__server__START_SSH_SERVER
value: "true"
- name: FORGEJO__server__SSH_PORT
value: "22"
- name: FORGEJO__server__SSH_LISTEN_PORT
value: "2222"
- name: FORGEJO__repository__DISABLE_HTTP_GIT
value: "true"
- name: FORGEJO__server__SSH_DOMAIN
value: "weaver.mynest.love"
# DB Config
- name: FORGEJO__database__DB_TYPE
value: "postgres"
- name: FORGEJO__database__HOST
value: "forgejo-db:5432"
- name: FORGEJO__database__NAME
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: POSTGRES_DB
- name: FORGEJO__database__USER
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: POSTGRES_USER
- name: FORGEJO__database__PASSWD
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: POSTGRES_PASSWORD
# Auth & Registration Controls
- name: FORGEJO__service__DISABLE_REGISTRATION
value: "false"
- name: FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION
value: "true" # Forces OIDC registration
- name: FORGEJO__service__SHOW_REGISTRATION_BUTTON
value: "false"
# Package & Container Registries
- name: FORGEJO__packages__ENABLED
value: "true"
# Secrets from Vault
- name: FORGEJO__security__SECRET_KEY
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: SECRET_KEY
- name: OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: OIDC_CLIENT_ID
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: forgejo-secrets
key: OIDC_CLIENT_SECRET
volumeMounts:
- name: forgejo-data
mountPath: /data
volumes:
- name: forgejo-data
persistentVolumeClaim:
claimName: forgejo-data
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo-db
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: forgejo-db
template:
metadata:
labels:
app: forgejo-db
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- containerPort: 5432
name: postgres
envFrom:
- secretRef:
name: forgejo-secrets
volumeMounts:
- name: forgejo-db-data
mountPath: /var/lib/postgresql/data
subPath: pgdata
volumes:
- name: forgejo-db-data
persistentVolumeClaim:
claimName: forgejo-db-data

View file

@ -0,0 +1,37 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: forgejo-secrets
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: forgejo-secrets
creationPolicy: Owner
data:
- secretKey: OIDC_CLIENT_ID
remoteRef:
key: forgejo
property: oidc_client_id
- secretKey: OIDC_CLIENT_SECRET
remoteRef:
key: forgejo
property: oidc_client_secret
- secretKey: SECRET_KEY
remoteRef:
key: forgejo
property: secret_key
- secretKey: POSTGRES_USER
remoteRef:
key: forgejo
property: db-user
- secretKey: POSTGRES_PASSWORD
remoteRef:
key: forgejo
property: db-pass
- secretKey: POSTGRES_DB
remoteRef:
key: forgejo
property: db-name

View file

@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: forgejo
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
tls:
- hosts:
- weaver.mynest.love
secretName: forgejo-tls
rules:
- host: weaver.mynest.love
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: forgejo
port:
name: http

View file

@ -0,0 +1,29 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-data
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-db-data
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,41 @@
apiVersion: v1
kind: Service
metadata:
name: forgejo
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: http
name: http
- port: 22
targetPort: ssh
name: ssh
selector:
app: forgejo
---
apiVersion: v1
kind: Service
metadata:
name: forgejo-db
spec:
type: ClusterIP
ports:
- port: 5432
targetPort: postgres
name: postgres
selector:
app: forgejo-db
---
apiVersion: v1
kind: Service
metadata:
name: forgejo-ssh-lb
spec:
type: LoadBalancer
ports:
- port: 22
targetPort: 2222
name: ssh
selector:
app: forgejo

View file

@ -2,6 +2,10 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: foundry-vtt
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
@ -41,18 +45,3 @@ spec:
- name: foundry-vtt-volume
persistentVolumeClaim:
claimName: foundry-vtt-data-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foundry-vtt-data-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View file

@ -6,7 +6,6 @@ metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: security-auth-foundryvtt@kubernetescrd
spec:
ingressClassName: traefik
tls:
@ -24,29 +23,3 @@ spec:
name: foundry-vtt
port:
name: http-web
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foundry-auth-ingress
namespace: security # MOVED TO SECURITY NAMESPACE
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
tls:
- hosts:
- foundry.mynest.love
secretName: foundry-vtt-tls
rules:
- host: foundry.mynest.love
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy-foundryvtt
port:
number: 4180

View file

@ -1,86 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: foundryvtt-proxy-foundryvtt
namespace: security
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy-foundryvtt
template:
metadata:
labels:
app: oauth2-proxy-foundryvtt
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
envFrom:
- secretRef:
name: foundry-oauth-secrets
args:
- "--provider=oidc"
- "--oidc-issuer-url=https://sso.mynest.love/realms/nest"
- "--oidc-groups-claim=groups"
- "--redirect-url=https://foundry.mynest.love/oauth2/callback"
- "--email-domain=*"
- "--allowed-group=foundryvtt"
- "--skip-provider-button=true"
- "--cookie-secure=true"
- "--cookie-domain=foundry.mynest.love"
- "--http-address=0.0.0.0:4180"
- "--reverse-proxy=true"
- "--upstream=static://200"
- "--whitelist-domain=foundry.mynest.love"
ports:
- containerPort: 4180
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: foundry-oauth-secrets
namespace: security
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: foundry-oauth-secrets
creationPolicy: Owner
data:
- secretKey: OAUTH2_PROXY_CLIENT_ID
remoteRef:
key: oauth2-proxy/foundryvtt
property: client-id
- secretKey: OAUTH2_PROXY_CLIENT_SECRET
remoteRef:
key: oauth2-proxy/foundryvtt
property: client-secret
- secretKey: OAUTH2_PROXY_COOKIE_SECRET
remoteRef:
key: oauth2-proxy/foundryvtt
property: cookie-secret
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy-foundryvtt
namespace: security
spec:
ports:
- port: 4180
targetPort: 4180
selector:
app: oauth2-proxy-foundryvtt
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-foundryvtt
namespace: security
spec:
forwardAuth:
address: "http://oauth2-proxy-foundryvtt.security.svc.cluster.local:4180"
trustForwardHeader: true

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foundry-vtt-data-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-jellyfin.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: jellyfin
name: jellyfin
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: jellyfin
app: jellyfin
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-jellyfin.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: jellyfin
app: jellyfin
spec:
containers:
- env:
@ -53,33 +49,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/media
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-cache-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 3Gi

View file

@ -1,7 +1,7 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: musicseerr-config-pvc
name: jellyfin-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
@ -16,7 +16,7 @@ spec:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: musicseerr-cache-pvc
name: jellyfin-cache-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-jellyfin.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: jellyfin
name: jellyfin
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: jellyfin
app: jellyfin

View file

@ -5,7 +5,7 @@ metadata:
namespace: security
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/critical-data: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "longhorn"

View file

@ -0,0 +1,62 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: matrix-secrets
namespace: matrix
spec:
refreshInterval: "1h"
secretStoreRef:
name: vault-external-secrets-store
kind: ClusterSecretStore
target:
name: matrix-secrets
creationPolicy: Owner
data:
- secretKey: LIVEKIT_KEY
remoteRef:
key: matrix
property: livekit-key
- secretKey: LIVEKIT_SECRET
remoteRef:
key: matrix
property: livekit-secret
- secretKey: CLIENT_ID
remoteRef:
key: matrix
property: client-id
- secretKey: CLIENT_SECRET
remoteRef:
key: matrix
property: client-secret
- secretKey: POSTGRES_USER
remoteRef:
key: matrix
property: postgres-user
- secretKey: POSTGRES_PASSWORD
remoteRef:
key: matrix
property: postgres-password
- secretKey: SYNAPSE_MACAROON_KEY
remoteRef:
key: matrix
property: synapse-macaroon
- secretKey: SYNAPSE_REGISTRATION_SECRET
remoteRef:
key: matrix
property: synapse-registration
- secretKey: MAS_SYNAPSE_ADMIN_SECRET
remoteRef:
key: matrix
property: mas-synapse-admin
- secretKey: MAS_SYNAPSE_CLIENT_SECRET
remoteRef:
key: matrix
property: mas-synapse-client
- secretKey: MAS_ENCRYPTION_SECRET
remoteRef:
key: matrix
property: mas-encryption-secret
- secretKey: MAS_RSA_KEY
remoteRef:
key: matrix
property: mas-rsa-key

View file

@ -0,0 +1,121 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-ingress
namespace: matrix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- starling.mynest.love
secretName: matrix-tls
rules:
- host: starling.mynest.love
http:
paths:
- path: /_matrix/client/v3/login
pathType: Prefix
backend:
service:
name: mas-svc
port:
number: 8080
- path: /_matrix/client/v3/logout
pathType: Prefix
backend:
service:
name: mas-svc
port:
number: 8080
- path: /_matrix/client/v3/refresh
pathType: Prefix
backend:
service:
name: mas-svc
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: synapse-svc
port:
number: 8008
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mas-ingress
namespace: matrix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- mas.mynest.love
secretName: mas-tls
rules:
- host: mas.mynest.love
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mas-svc
port:
number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-rtc-ingress
namespace: matrix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- matrix-rtc.mynest.love
secretName: matrix-rtc-tls
rules:
- host: matrix-rtc.mynest.love
http:
paths:
# 1. Route token generation & webhook traffic to the lk-jwt-service
- path: /sfu/get
pathType: Prefix
backend:
service:
name: lk-jwt-svc
port:
number: 8080
- path: /get_token
pathType: Prefix
backend:
service:
name: lk-jwt-svc
port:
number: 8080
- path: /sfu_webhook
pathType: Prefix
backend:
service:
name: lk-jwt-svc
port:
number: 8080
# 2. Route all standard traffic and WebSockets to LiveKit
- path: /
pathType: Prefix
backend:
service:
name: livekit-svc
port:
number: 7880

View file

@ -0,0 +1,123 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: livekit-config-tmpl
namespace: matrix
data:
livekit.yaml: |
port: 7880
rtc:
tcp_port: 7881
udp_port: 7882
use_external_ip: false
node_ip: "192.168.1.160"
turn:
cert_file: ""
key_file: ""
tls_port: 0
udp_port: 3478
external_tls: false
# Crucial for Matrix integration: Only the JWT service can create rooms
room:
auto_create: false
webhook:
api_key: "${LIVEKIT_KEY}" # Swapped to match the key name inside matrix-secrets
urls:
- https://matrix-rtc.mynest.love/sfu_webhook
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: livekit
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: livekit
template:
metadata:
labels:
app: livekit
spec:
initContainers:
- name: generate-config
image: alpine:latest
command: ["/bin/sh", "-c", "apk add gettext && envsubst < /tmpl/livekit.yaml > /etc/livekit/livekit.yaml"]
envFrom:
- secretRef:
name: matrix-secrets
volumeMounts:
- name: config-tmpl
mountPath: /tmpl/livekit.yaml
subPath: livekit.yaml
- name: livekit-runtime-config
mountPath: /etc/livekit
containers:
- name: livekit
image: livekit/livekit-server:latest
args: ["--config", "/etc/livekit/livekit.yaml"] # Point to the generated file path
ports:
- containerPort: 7880
- containerPort: 7881
- containerPort: 7882
protocol: UDP
- containerPort: 3478
protocol: UDP
env:
- name: LK_KEY
valueFrom:
secretKeyRef:
name: matrix-secrets
key: LIVEKIT_KEY
- name: LK_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: LIVEKIT_SECRET
- name: LIVEKIT_KEYS
value: '$(LK_KEY): $(LK_SECRET)'
volumeMounts:
- name: livekit-runtime-config
mountPath: /etc/livekit
volumes:
- name: livekit-runtime-config
emptyDir: {}
- name: config-tmpl
configMap:
name: livekit-config-tmpl
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lk-jwt-service
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: lk-jwt-service
template:
metadata:
labels:
app: lk-jwt-service
spec:
hostAliases:
- ip: "192.168.1.150"
hostnames:
- "starling.mynest.love"
- "mas.mynest.love"
- "matrix-rtc.mynest.love"
containers:
- name: lk-jwt-service
image: ghcr.io/element-hq/lk-jwt-service:0.4.2
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: matrix-secrets
env:
- name: LIVEKIT_URL
value: "wss://matrix-rtc.mynest.love"
- name: LIVEKIT_FULL_ACCESS_HOMESERVERS
value: "starling.mynest.love"

View file

@ -0,0 +1,111 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mas-config-tmpl
namespace: matrix
data:
config.yaml: |
http:
listeners:
- name: web
resources:
- name: discovery
- name: human
- name: oauth
- name: compat
- name: graphql
- name: assets
binds:
- host: "::"
port: 8080
public_base: "https://mas.mynest.love/"
database:
uri: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres-svc:5432/mas"
matrix:
homeserver: "starling.mynest.love"
endpoint: "http://synapse-svc:8008"
secret: "${MAS_SYNAPSE_ADMIN_SECRET}"
clients:
- client_id: "0000000000000000000SYNAPSE"
client_auth_method: client_secret_basic
client_secret: "${MAS_SYNAPSE_CLIENT_SECRET}"
upstream_oauth2:
providers:
- id: 01J1ABCD2345EFGH6789JKMNPQ
issuer: "https://sso.mynest.love/realms/nest"
client_id: "${CLIENT_ID}"
client_secret: "${CLIENT_SECRET}"
token_endpoint_auth_method: "client_secret_basic"
scope: "openid profile email"
claims_imports:
subject:
template: "{{ user.sub }}"
localpart:
action: "ignore"
displayname:
action: "suggest"
template: "{{ user.name }}"
email:
action: "suggest"
template: "{{ user.email }}"
set_email_verification: "always"
secrets:
encryption: "${MAS_ENCRYPTION_SECRET}"
keys:
- key_file: "/secrets/MAS_RSA_KEY"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mas
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: mas
template:
metadata:
labels:
app: mas
spec:
initContainers:
- name: generate-config
image: alpine:latest
command: ["/bin/sh", "-c", "apk add gettext && envsubst < /tmpl/config.yaml > /data/config.yaml"]
envFrom:
- secretRef:
name: matrix-secrets
volumeMounts:
- name: config-tmpl
mountPath: /tmpl/config.yaml
subPath: config.yaml
- name: mas-data
mountPath: /data
containers:
- name: mas
image: ghcr.io/element-hq/matrix-authentication-service:latest
env:
- name: MAS_CONFIG
value: "/data/config.yaml"
ports:
- containerPort: 8080
volumeMounts:
- name: mas-data
mountPath: /data
- name: secrets-volume
mountPath: /secrets
readOnly: true
volumes:
- name: mas-data
emptyDir: {}
- name: config-tmpl
configMap:
name: mas-config-tmpl
- name: secrets-volume
secret:
secretName: matrix-secrets

View file

@ -0,0 +1,57 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-init-script
namespace: matrix
data:
init-multiple-dbs.sql: |
CREATE DATABASE synapse;
CREATE DATABASE mas;
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: matrix-secrets
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: POSTGRES_PASSWORD
- name: POSTGRES_INITDB_ARGS
value: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
subPath: synapse-data
- name: init-script
mountPath: /docker-entrypoint-initdb.d/init-multiple-dbs.sql
subPath: init-multiple-dbs.sql
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgres-data
- name: init-script
configMap:
name: postgres-init-script

View file

@ -0,0 +1,31 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: synapse-data
namespace: matrix
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: matrix
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,82 @@
apiVersion: v1
kind: Service
metadata:
name: synapse-svc
namespace: matrix
spec:
selector:
app: synapse
ports:
- protocol: TCP
port: 8008
targetPort: 8008
---
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
namespace: matrix
spec:
selector:
app: postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432
---
apiVersion: v1
kind: Service
metadata:
name: mas-svc
namespace: matrix
spec:
selector:
app: mas
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: livekit-svc
namespace: matrix
annotations:
# Tell MetalLB to assign this specific IP from the nest-lb-pool
metallb.universe.tf/loadBalancerIPs: 192.168.1.160
spec:
# Using LoadBalancer to expose the UDP WebRTC ports directly
type: LoadBalancer
selector:
app: livekit
ports:
- name: http
port: 7880
targetPort: 7880
protocol: TCP
- name: rtc-tcp
port: 7881
targetPort: 7881
protocol: TCP
- name: rtc-udp
port: 7882
targetPort: 7882
protocol: UDP
- name: turn-udp
port: 3478
targetPort: 3478
protocol: UDP
---
apiVersion: v1
kind: Service
metadata:
name: lk-jwt-svc
namespace: matrix
spec:
selector:
app: lk-jwt-service
ports:
- protocol: TCP
port: 8080
targetPort: 8080

View file

@ -0,0 +1,109 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: synapse-config-tmpl
namespace: matrix
data:
homeserver.yaml: |
server_name: "starling.mynest.love"
public_baseurl: "https://starling.mynest.love"
media_store_path: "/data/media_store"
uploads_path: "/data/uploads"
serve_server_wellknown: true
serve_client_wellknown: true
extra_well_known_client_content:
"org.matrix.msc4143.rtc_foci":
- type: livekit
livekit_service_url: "https://matrix-rtc.mynest.love"
matrix_rtc:
transports:
- type: livekit
livekit_service_url: "https://matrix-rtc.mynest.love"
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: "${POSTGRES_USER}"
password: "${POSTGRES_PASSWORD}"
database: "synapse"
host: "postgres-svc"
cp_min: 5
cp_max: 10
experimental_features:
msc4140_enabled: true
msc4143_enabled: true
msc4222_enabled: true
msc3861:
enabled: true
issuer: "https://mas.mynest.love/"
client_id: "0000000000000000000SYNAPSE"
client_auth_method: client_secret_basic
client_secret: "${MAS_SYNAPSE_CLIENT_SECRET}"
admin_token: "${MAS_SYNAPSE_ADMIN_SECRET}"
macaroon_secret_key: "${SYNAPSE_MACAROON_KEY}"
form_secret: "${SYNAPSE_REGISTRATION_SECRET}"
registration_shared_secret: "${SYNAPSE_REGISTRATION_SECRET}"
enable_registration: false
report_stats: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: synapse
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app: synapse
template:
metadata:
labels:
app: synapse
spec:
initContainers:
- name: generate-config
image: alpine:latest
command: ["/bin/sh", "-c", "apk add gettext && envsubst < /tmpl/homeserver.yaml > /data/homeserver.yaml && chown -R 991:991 /data"]
envFrom:
- secretRef:
name: matrix-secrets
volumeMounts:
- name: config-tmpl
mountPath: /tmpl/homeserver.yaml
subPath: homeserver.yaml
- name: synapse-data
mountPath: /data
containers:
- name: synapse
image: matrixdotorg/synapse:latest
ports:
- containerPort: 8008
env:
- name: SYNAPSE_CONFIG_PATH
value: "/data/homeserver.yaml"
volumeMounts:
- name: synapse-data
mountPath: /data
volumes:
- name: synapse-data
persistentVolumeClaim:
claimName: synapse-data
- name: config-tmpl
configMap:
name: synapse-config-tmpl

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: prowlarr
name: prowlarr
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: prowlarr
app: prowlarr
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: prowlarr
app: prowlarr
spec:
containers:
- env:
@ -44,18 +40,3 @@ spec:
- name: prowlarr-config
persistentVolumeClaim:
claimName: prowlarr-config-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 200Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: prowlarr
name: prowlarr
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: prowlarr
app: prowlarr

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr-anime
name: radarr-anime
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: radarr-anime
app: radarr-anime
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr-anime
app: radarr-anime
spec:
containers:
- env:
@ -56,18 +52,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/downloads
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-anime-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 150Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-anime-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 150Mi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr-anime
name: radarr-anime
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: radarr-anime
app: radarr-anime

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr
name: radarr
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: radarr
app: radarr
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr
app: radarr
spec:
containers:
- env:
@ -56,18 +52,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/downloads
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 150Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 150Mi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: radarr
name: radarr
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: radarr
app: radarr

View file

@ -1,26 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: sabnzbd
name: sabnzbd
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: sabnzbd
app: sabnzbd
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: sabnzbd
app: sabnzbd
spec:
containers:
- env:
@ -50,18 +46,3 @@ spec:
nfs:
server: robin.home.nest
path: /yarr/downloads
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sabnzbd-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 50Mi

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sabnzbd-config-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 50Mi

View file

@ -1,11 +1,6 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f compose-yarr.yaml
kompose.version: 1.38.0 (HEAD)
labels:
io.kompose.service: sabnzbd
name: sabnzbd
spec:
type: ClusterIP
@ -14,4 +9,4 @@ spec:
port: 80
targetPort: web-ui
selector:
io.kompose.service: sabnzbd
app: sabnzbd

View file

@ -1,21 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: jellyseerr
name: jellyseerr
name: seerr
annotations:
keel.sh/policy: "all"
keel.sh/match-tag: "true"
keel.sh/schedule: "0 3 * * *"
spec:
replicas: 1
selector:
matchLabels:
app: jellyseerr
app: seerr
strategy:
type: Recreate
template:
metadata:
labels:
app: jellyseerr
app: seerr
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
containers:
- env:
- name: PGID
@ -26,17 +32,17 @@ spec:
value: "3000"
- name: TZ
value: America/New_York
image: fallenbagel/jellyseerr:preview-OIDC
name: jellyseerr
image: ghcr.io/seerr-team/seerr:preview-new-oidc
name: seerr
ports:
- containerPort: 5055
protocol: TCP
name: web-ui
volumeMounts:
- mountPath: /app/config
name: jellyseerr-volume
name: seerr-volume
restartPolicy: Always
volumes:
- name: jellyseerr-volume
- name: seerr-volume
persistentVolumeClaim:
claimName: jellyseerr-data-pvc
claimName: seerr-data-pvc

View file

@ -1,7 +1,7 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jellyseerr-ingress
name: seerr-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
@ -11,7 +11,7 @@ spec:
tls:
- hosts:
- stork.mynest.love
secretName: jellyseerr-tls
secretName: seerr-tls
rules:
- host: stork.mynest.love
http:
@ -20,6 +20,6 @@ spec:
pathType: Prefix
backend:
service:
name: jellyseerr
name: seerr
port:
name: http-web

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: seerr-data-pvc
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/app-config-group: "enabled"
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 20Mi

Some files were not shown because too many files have changed in this diff Show more