feat(infra): media stack, Vaultwarden, Cloudflare tunnel, OIDC providers, Caddy TLS

- Media stack deployed: qBittorrent, Sonarr, Radarr, Lidarr, Prowlarr, Bazarr,
  Navidrome, Audiobookshelf, Jellyfin, Homarr, Kavita, MeTube, SuggestArr, BoxArr
- Romm, ebook2audiobook (GPU CUDA), TrailBase, FlareSolverr deployed
- Vaultwarden + Vaultwarden-API deployed
- Caddy reverse proxy on racknerd with Let's Encrypt TLS at *.researchstack.info
- Authentik 7 OIDC providers + 12 proxy providers for SSO
- NVIDIA GPU support enabled on k3s (device plugin + containerd runtime)
- Cloudflare tunnel created (DNS on Porkbun)

Build: 3313 jobs, 0 errors (lake build Compiler)
This commit is contained in:
Brandon Schneider 2026-05-31 11:01:39 -05:00
parent 7c1f690e0f
commit 0d87bcb770
16 changed files with 1737 additions and 0 deletions

View file

@ -0,0 +1,79 @@
{
admin off
email bigdataiscoming@protonmail.com
}
researchstack.info {
redir https://www.researchstack.info{uri}
}
auth.researchstack.info {
reverse_proxy http://100.88.57.96:30080
}
flaresolverr.researchstack.info {
reverse_proxy http://100.88.57.96:30105
}
www.researchstack.info {
forward_auth http://100.88.57.96:30080 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-User X-Authentik-Username X-Authentik-Groups X-Authentik-Email
}
reverse_proxy http://100.88.57.96:30093
}
uptime.researchstack.info {
forward_auth http://100.88.57.96:30080 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-User X-Authentik-Username
}
reverse_proxy http://100.88.57.96:30081
}
media.researchstack.info {
forward_auth http://100.88.57.96:30080 {
uri /outpost.goauthentik.io/auth/caddy
}
reverse_proxy http://100.88.57.96:30091
}
music.researchstack.info {
reverse_proxy http://100.88.57.96:30089
}
books.researchstack.info {
reverse_proxy http://100.88.57.96:30094
}
audiobooks.researchstack.info {
reverse_proxy http://100.88.57.96:30090
}
movies.researchstack.info {
reverse_proxy http://100.88.57.96:30086
}
tv.researchstack.info {
reverse_proxy http://100.88.57.96:30085
}
downloads.researchstack.info {
reverse_proxy http://100.88.57.96:30082
}
vault.researchstack.info {
reverse_proxy http://100.88.57.96:30106
}
vaultapi.researchstack.info {
reverse_proxy http://100.88.57.96:30107
}
trailbase.researchstack.info {
reverse_proxy http://100.88.57.96:30104
}
ebook.researchstack.info {
reverse_proxy http://100.88.57.96:30103
}

View file

@ -0,0 +1,142 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: radarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: radarr
template:
metadata:
labels:
app: radarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: radarr
image: lscr.io/linuxserver/radarr:latest
ports:
- containerPort: 7878
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/downloads
subPath: downloads
- name: media
mountPath: /media/movies
subPath: movies
volumes:
- name: config
persistentVolumeClaim:
claimName: radarr-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: radarr
namespace: media
spec:
type: NodePort
ports:
- port: 7878
targetPort: 7878
nodePort: 30086
selector:
app: radarr
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lidarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lidarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: lidarr
template:
metadata:
labels:
app: lidarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: lidarr
image: lscr.io/linuxserver/lidarr:latest
ports:
- containerPort: 8686
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/downloads
subPath: downloads
- name: media
mountPath: /media/music
subPath: music
volumes:
- name: config
persistentVolumeClaim:
claimName: lidarr-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: lidarr
namespace: media
spec:
type: NodePort
ports:
- port: 8686
targetPort: 8686
nodePort: 30087
selector:
app: lidarr

View file

@ -0,0 +1,154 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: audiobookshelf-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: audiobookshelf
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: audiobookshelf
template:
metadata:
labels:
app: audiobookshelf
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: audiobookshelf
image: ghcr.io/advplyr/audiobookshelf:latest
ports:
- containerPort: 13378
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /audiobooks
subPath: audiobooks
- name: media
mountPath: /podcasts
subPath: podcasts
volumes:
- name: config
persistentVolumeClaim:
claimName: audiobookshelf-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: audiobookshelf
namespace: media
spec:
type: NodePort
ports:
- port: 13378
targetPort: 13378
nodePort: 30090
selector:
app: audiobookshelf
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jellyfin
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: jellyfin
template:
metadata:
labels:
app: jellyfin
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: jellyfin
image: lscr.io/linuxserver/jellyfin:latest
ports:
- containerPort: 8096
- containerPort: 8920
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/movies
subPath: movies
- name: media
mountPath: /media/tv
subPath: tv
- name: media
mountPath: /media/music
subPath: music
- name: media
mountPath: /media/audiobooks
subPath: audiobooks
volumes:
- name: config
persistentVolumeClaim:
claimName: jellyfin-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: jellyfin
namespace: media
spec:
type: NodePort
ports:
- name: web
port: 8096
targetPort: 8096
nodePort: 30091
- name: https
port: 8920
targetPort: 8920
nodePort: 30092
selector:
app: jellyfin

View file

@ -0,0 +1,40 @@
global:
nodeSelector:
kubernetes.io/hostname: qfox-1
authentik:
log_level: info
secret_key: "" # Will be auto-generated
bootstrap_password: "authentik"
bootstrap_token: "authentik-bootstrap-token"
email:
host: ""
port: 587
username: ""
password: ""
postgresql:
enabled: true
persistence:
enabled: true
size: 10Gi
primary:
nodeSelector:
kubernetes.io/hostname: qfox-1
redis:
enabled: true
master:
nodeSelector:
kubernetes.io/hostname: qfox-1
server:
service:
type: NodePort
nodePort: 30095
ingress:
enabled: false
worker:
nodeSelector:
kubernetes.io/hostname: qfox-1

View file

@ -0,0 +1,139 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bazarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: bazarr
template:
metadata:
labels:
app: bazarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: bazarr
image: lscr.io/linuxserver/bazarr:latest
ports:
- containerPort: 6767
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/movies
subPath: movies
- name: media
mountPath: /media/tv
subPath: tv
volumes:
- name: config
persistentVolumeClaim:
claimName: bazarr-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: bazarr
namespace: media
spec:
type: NodePort
ports:
- port: 6767
targetPort: 6767
nodePort: 30088
selector:
app: bazarr
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: navidrome-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: navidrome
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: navidrome
template:
metadata:
labels:
app: navidrome
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: navidrome
image: deluan/navidrome:latest
ports:
- containerPort: 4533
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /data
- name: media
mountPath: /music
subPath: music
volumes:
- name: config
persistentVolumeClaim:
claimName: navidrome-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: navidrome
namespace: media
spec:
type: NodePort
ports:
- port: 4533
targetPort: 4533
nodePort: 30089
selector:
app: navidrome

View file

@ -0,0 +1,126 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: e2a-ebooks
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: local-path
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: e2a-audiobooks
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: local-path
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: e2a-models
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
storageClassName: local-path
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: e2a-voices
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ebook2audiobook
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: ebook2audiobook
template:
metadata:
labels:
app: ebook2audiobook
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: e2a
image: athomasson2/ebook2audiobook:cu128
ports:
- containerPort: 7860
env:
- name: GRADIO_SERVER_NAME
value: "0.0.0.0"
resources:
limits:
nvidia.com/gpu: 1
memory: "16Gi"
cpu: "4"
requests:
memory: "4Gi"
cpu: "1"
volumeMounts:
- name: ebooks
mountPath: /app/ebooks
- name: audiobooks
mountPath: /app/audiobooks
- name: models
mountPath: /app/models
- name: voices
mountPath: /app/voices
- name: tmp
mountPath: /app/tmp
volumes:
- name: ebooks
persistentVolumeClaim:
claimName: e2a-ebooks
- name: audiobooks
persistentVolumeClaim:
claimName: e2a-audiobooks
- name: models
persistentVolumeClaim:
claimName: e2a-models
- name: voices
persistentVolumeClaim:
claimName: e2a-voices
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: ebook2audiobook
namespace: media
spec:
type: NodePort
ports:
- port: 7860
targetPort: 7860
nodePort: 30103
selector:
app: ebook2audiobook

View file

@ -0,0 +1,128 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: homarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: homarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: homarr
template:
metadata:
labels:
app: homarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: homarr
image: ghcr.io/ajnart/homarr:latest
ports:
- containerPort: 7575
volumeMounts:
- name: config
mountPath: /app/data
volumes:
- name: config
persistentVolumeClaim:
claimName: homarr-config
---
apiVersion: v1
kind: Service
metadata:
name: homarr
namespace: media
spec:
type: NodePort
ports:
- port: 7575
targetPort: 7575
nodePort: 30093
selector:
app: homarr
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: kavita-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kavita
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: kavita
template:
metadata:
labels:
app: kavita
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: kavita
image: jvmilazz0/kavita:latest
ports:
- containerPort: 5000
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /kavita/config
- name: media
mountPath: /kavita/books
subPath: books
- name: media
mountPath: /kavita/comics
subPath: comics
volumes:
- name: config
persistentVolumeClaim:
claimName: kavita-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: kavita
namespace: media
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30094
selector:
app: kavita

View file

@ -0,0 +1,42 @@
apiVersion: v1
kind: Namespace
metadata:
name: media
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: media-store
spec:
capacity:
storage: 1Ti
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /var/lib/media
type: DirectoryOrCreate
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- qfox-1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: media-store
namespace: media
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Ti
storageClassName: manual
volumeMode: Filesystem

View file

@ -0,0 +1,159 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: metube-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metube
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: metube
template:
metadata:
labels:
app: metube
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: metube
image: ghcr.io/alexta69/metube:latest
ports:
- containerPort: 8081
volumeMounts:
- name: media
mountPath: /downloads
subPath: downloads
volumes:
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: metube
namespace: media
spec:
type: NodePort
ports:
- port: 8081
targetPort: 8081
nodePort: 30096
selector:
app: metube
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: suggestarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: suggestarr
template:
metadata:
labels:
app: suggestarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: suggestarr
image: ciuse99/suggestarr:latest
ports:
- containerPort: 5000
env:
- name: PORT
value: "5000"
- name: SUGGESTARR_PORT
value: "5000"
env:
- name: SONARR_URL
value: "http://sonarr:8989"
- name: RADARR_URL
value: "http://radarr:7878"
- name: LIDARR_URL
value: "http://lidarr:8686"
volumeMounts:
- name: config
mountPath: /app/config
volumes:
- name: config
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: suggestarr-app
namespace: media
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30097
selector:
app: suggestarr
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: boxarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: boxarr
template:
metadata:
labels:
app: boxarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: boxarr
image: ghcr.io/iongpt/boxarr:latest
ports:
- containerPort: 5000
env:
- name: BOXARR_PORT
value: "5000"
volumeMounts:
- name: config
mountPath: /app/data
volumes:
- name: config
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: boxarr
namespace: media
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30098
selector:
app: boxarr

View file

@ -0,0 +1,62 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prowlarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: prowlarr
template:
metadata:
labels:
app: prowlarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: prowlarr
image: lscr.io/linuxserver/prowlarr:latest
ports:
- containerPort: 9696
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
persistentVolumeClaim:
claimName: prowlarr-config
---
apiVersion: v1
kind: Service
metadata:
name: prowlarr
namespace: media
spec:
type: NodePort
ports:
- port: 9696
targetPort: 9696
nodePort: 30084
selector:
app: prowlarr

View file

@ -0,0 +1,76 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qbittorrent-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: qbittorrent
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: qbittorrent
template:
metadata:
labels:
app: qbittorrent
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:latest
ports:
- containerPort: 8080
- containerPort: 6881
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
- name: UMASK
value: "002"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/downloads
subPath: downloads
volumes:
- name: config
persistentVolumeClaim:
claimName: qbittorrent-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: qbittorrent
namespace: media
spec:
type: NodePort
ports:
- name: webui
port: 8080
targetPort: 8080
nodePort: 30082
- name: bittorrent
port: 6881
targetPort: 6881
nodePort: 30083
selector:
app: qbittorrent

View file

@ -0,0 +1,214 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: romm-mysql
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-path
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: romm-resources
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-path
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: romm-redis
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: romm-db
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: romm-db
template:
metadata:
labels:
app: romm-db
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: mariadb
image: mariadb:latest
ports:
- containerPort: 3306
env:
- name: MARIADB_ROOT_PASSWORD
value: "romm-root-pw"
- name: MARIADB_DATABASE
value: "romm"
- name: MARIADB_USER
value: "romm"
- name: MARIADB_PASSWORD
value: "romm-db-pw"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
livenessProbe:
exec:
command: [healthcheck.sh, --connect, --innodb_initialized]
initialDelaySeconds: 30
periodSeconds: 10
volumes:
- name: data
persistentVolumeClaim:
claimName: romm-mysql
---
apiVersion: v1
kind: Service
metadata:
name: romm-db
namespace: media
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: romm-db
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: romm-redis
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: romm-redis
template:
metadata:
labels:
app: romm-redis
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: romm-redis
---
apiVersion: v1
kind: Service
metadata:
name: romm-redis
namespace: media
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: romm-redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: romm
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: romm
template:
metadata:
labels:
app: romm
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: romm
image: rommapp/romm:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "romm-db"
- name: DB_NAME
value: "romm"
- name: DB_USER
value: "romm"
- name: DB_PASSWD
value: "romm-db-pw"
- name: ROMM_AUTH_SECRET_KEY
value: "change-me-romm-secret-key-32bytes-hex00000"
- name: REDIS_HOST
value: "romm-redis"
- name: REDIS_PORT
value: "6379"
- name: ROMM_PORT
value: "8080"
- name: HASHEOUS_API_ENABLED
value: "true"
volumeMounts:
- name: library
mountPath: /romm/library
subPath: games
- name: assets
mountPath: /romm/assets
- name: config
mountPath: /romm/config
- name: resources
mountPath: /romm/resources
volumes:
- name: library
persistentVolumeClaim:
claimName: media-store
- name: assets
emptyDir: {}
- name: config
emptyDir: {}
- name: resources
persistentVolumeClaim:
claimName: romm-resources
---
apiVersion: v1
kind: Service
metadata:
name: romm
namespace: media
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30099
selector:
app: romm

View file

@ -0,0 +1,71 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sonarr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: sonarr
template:
metadata:
labels:
app: sonarr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: sonarr
image: lscr.io/linuxserver/sonarr:latest
ports:
- containerPort: 8989
env:
- name: PUID
value: "1000"
- name: PGID
value: "100"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/downloads
subPath: downloads
- name: media
mountPath: /media/tv
subPath: tv
volumes:
- name: config
persistentVolumeClaim:
claimName: sonarr-config
- name: media
persistentVolumeClaim:
claimName: media-store
---
apiVersion: v1
kind: Service
metadata:
name: sonarr
namespace: media
spec:
type: NodePort
ports:
- port: 8989
targetPort: 8989
nodePort: 30085
selector:
app: sonarr

View file

@ -0,0 +1,110 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: trailbase-depot
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: trailbase
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: trailbase
template:
metadata:
labels:
app: trailbase
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: trailbase
image: trailbase/trailbase:latest
command: ["/app/trail", "run"]
ports:
- containerPort: 4000
env:
- name: ADDRESS
value: "0.0.0.0:4000"
volumeMounts:
- name: depot
mountPath: /app/traildepot
volumes:
- name: depot
persistentVolumeClaim:
claimName: trailbase-depot
---
apiVersion: v1
kind: Service
metadata:
name: trailbase
namespace: media
spec:
type: NodePort
ports:
- port: 4000
targetPort: 4000
nodePort: 30104
selector:
app: trailbase
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: flaresolverr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: flaresolverr
template:
metadata:
labels:
app: flaresolverr
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: flaresolverr
image: ghcr.io/flaresolverr/flaresolverr:latest
ports:
- containerPort: 8191
env:
- name: LOG_LEVEL
value: "info"
- name: HEADLESS
value: "true"
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2"
---
apiVersion: v1
kind: Service
metadata:
name: flaresolverr
namespace: media
spec:
type: NodePort
ports:
- port: 8191
targetPort: 8191
nodePort: 30105
selector:
app: flaresolverr

View file

@ -0,0 +1,65 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: uptime-kuma-data
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: uptime-kuma
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: uptime-kuma
template:
metadata:
labels:
app: uptime-kuma
spec:
containers:
- name: uptime-kuma
image: louislam/uptime-kuma:latest
ports:
- containerPort: 3001
volumeMounts:
- name: data
mountPath: /app/data
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: data
persistentVolumeClaim:
claimName: uptime-kuma-data
---
apiVersion: v1
kind: Service
metadata:
name: uptime-kuma
namespace: monitoring
spec:
type: NodePort
ports:
- port: 3001
targetPort: 3001
nodePort: 30081
selector:
app: uptime-kuma

View file

@ -0,0 +1,130 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultwarden
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: vaultwarden
template:
metadata:
labels:
app: vaultwarden
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: vaultwarden
image: vaultwarden/server:latest
ports:
- containerPort: 80
env:
- name: SIGNUPS_ALLOWED
value: "false"
- name: DOMAIN
value: "https://vault.researchstack.info"
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: vaultwarden-data
---
apiVersion: v1
kind: Service
metadata:
name: vaultwarden
namespace: media
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30106
selector:
app: vaultwarden
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-api
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultwarden-api
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: vaultwarden-api
template:
metadata:
labels:
app: vaultwarden-api
spec:
nodeSelector:
kubernetes.io/hostname: qfox-1
containers:
- name: api
image: ghcr.io/turbootzz/vaultwarden-api:latest
ports:
- containerPort: 8080
env:
- name: VAULTWARDEN_URL
value: "http://vaultwarden:80"
- name: VAULTWARDEN_EMAIL
value: "secrets@researchstack.info"
- name: VAULTWARDEN_PASSWORD
value: "changeme-vaultwarden-password"
- name: API_KEY
value: "change-me-vaultwarden-api-key-min-32-chars!!"
- name: ENVIRONMENT
value: "production"
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: vaultwarden-api
---
apiVersion: v1
kind: Service
metadata:
name: vaultwarden-api
namespace: media
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30107
selector:
app: vaultwarden-api