first commit

This commit is contained in:
2025-07-04 19:51:51 +05:30
commit 42895beb8c
72 changed files with 2584 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: authelia
description: A Helm chart for Authelia
type: application
version: 0.1.0
appVersion: "4"

View File

@@ -0,0 +1,15 @@
name: authelia
namespace: prod
image:
repository: authelia/authelia
tag: 4
persistence:
enabled: true
existingClaim: true
claimName: longhorn-authelia
service:
type: LoadBalancer
port: 9091

View File

@@ -0,0 +1,16 @@
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "NodePort" }}
type: NodePort
{{- else if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- targetPort: 9091
protocol: TCP
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,34 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
volumeMounts:
- name: config
mountPath: /config
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: bazarr
description: A Helm chart for Bazarr
type: application
version: 0.1.0
appVersion: "1.5.2"

View File

@@ -0,0 +1,32 @@
name: bazarr
namespace: prod
image:
repository: ghcr.io/linuxserver/bazarr
tag: 1.5.2
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
env:
PUID: 1000
PGID: 1000
TZ: Asia/Kolkata
persistence:
enabled: true
size: 500Mi
volumes:
tv:
server: 10.0.0.123
path: /merge/series
movies:
server: 10.0.0.123
path: /merge/movies
service:
type: LoadBalancer
port: 6767

View File

@@ -0,0 +1,16 @@
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "NodePort" }}
type: NodePort
{{- else if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- protocol: TCP
targetPort: 6767
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,58 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
securityContext:
runAsUser: {{ .Values.securityContext.runAsUser }}
runAsGroup: {{ .Values.securityContext.runAsGroup }}
fsGroup: {{ .Values.securityContext.fsGroup }}
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
env:
- name: PUID
value: "{{ .Values.env.PUID }}"
- name: PGID
value: "{{ .Values.env.PGID }}"
- name: TZ
value: "{{ .Values.env.TZ }}"
volumeMounts:
- name: movies
mountPath: /movies
- name: tv
mountPath: /tv
- name: config
mountPath: /config
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}
- name: tv
nfs:
server: {{ .Values.volumes.tv.server }}
path: {{ .Values.volumes.tv.path }}
- name: movies
nfs:
server: {{ .Values.volumes.movies.server }}
path: {{ .Values.volumes.movies.path }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: code-server
description: A Helm chart for Code-Server
type: application
version: 0.1.0
appVersion: "4.101.2"

View File

@@ -0,0 +1,29 @@
name: code-server
namespace: prod
image:
repository: lscr.io/linuxserver/code-server
tag: 4.101.2
env:
PUID: 1000
PGID: 1000
TZ: Asia/Kolkata
DEFAULT_WORKSPACE: /config/workspace
secrets:
PASSWORD:
name: code-server-secrets
key: PASSWORD
SUDO_PASSWORD:
name: code-server-secrets
key: SUDO_PASSWORD
persistence:
enabled: true
existingClaim: true
claimName: longhorn-code-server
service:
type: LoadBalancer
port: 8443

View File

@@ -0,0 +1,16 @@
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: {{ .Values.name }}
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
ports:
- targetPort: 8443
protocol: TCP
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,54 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
env:
- name: PUID
value: "{{ .Values.env.PUID }}"
- name: PGID
value: "{{ .Values.env.PGID }}"
- name: TZ
value: "{{ .Values.env.TZ }}"
- name: PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.PASSWORD.name }}
key: {{ .Values.secrets.PASSWORD.key }}
- name: SUDO_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.SUDO_PASSWORD.name }}
key: {{ .Values.secrets.SUDO_PASSWORD.key }}
- name: DEFAULT_WORKSPACE
value: "{{ .Values.env.DEFAULT_WORKSPACE }}"
volumeMounts:
- name: code-server
mountPath: /config
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: drone
description: A Helm chart for Drone CI/CD
type: application
version: 0.1.0
appVersion: "2"

View File

@@ -0,0 +1,41 @@
name: drone
namespace: prod
image:
server:
repository: drone/drone
tag: 2
runner:
repository: drone/drone-runner-kube
tag: latest
gitea:
service:
name: gitea-int-service
port: 3000
server:
env:
url: https://gitea.akshun-lab.uk
host: drone.akshun-lab.uk
proto: https
secrets:
DRONE_GITEA_CLIENT_ID:
secretName: drone-gitea-secrets
key: client_id
DRONE_GITEA_CLIENT_SECRET:
secretName: drone-gitea-secrets
key: client_secret
DRONE_RPC_SECRET:
secretName: drone-gitea-secrets
key: rpc_secret
persistence:
enabled: true
existingClaim: true
claimName: longhorn-drone
service:
type: LoadBalancer
port: 4338

View File

@@ -0,0 +1,16 @@
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,40 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: {{ .Values.namespace }}
name: {{ .Values.name }}
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- apiGroups:
- ""
resources:
- pods
- pods/log
verbs:
- get
- create
- delete
- list
- watch
- update
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
subjects:
- kind: ServiceAccount
name: default
namespace: {{ .Values.namespace }}
roleRef:
kind: Role
name: {{ .Values.name }}
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app.kubernetes.io/name: {{ .Values.name }}
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
ports:
- {{- if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
targetPort: 80
protocol: TCP

View File

@@ -0,0 +1,84 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ .Values.name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Values.name }}
spec:
initContainers:
- name: wait-for-gitea
image: busybox
command:
- sh
- -c
- |
while ! nc -z {{ .Values.gitea.service.name }} {{ .Values.gitea.service.port }}; do
echo "Waiting for Gitea to be ready..."
sleep 5
done
echo "Gitea is ready!"
- name: "{{ .Values.name }}-server"
image: "{{ .Values.image.server.repository }}:{{ .Values.image.server.tag }}"
restartPolicy: Always
env:
- name: DRONE_GITEA_SERVER
value: "{{ .Values.server.env.url }}"
- name: DRONE_GITEA_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.DRONE_GITEA_CLIENT_ID.secretName }}
key: {{ .Values.secrets.DRONE_GITEA_CLIENT_ID.key }}
- name: DRONE_GITEA_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.DRONE_GITEA_CLIENT_SECRET.secretName }}
key: {{ .Values.secrets.DRONE_GITEA_CLIENT_SECRET.key }}
- name: DRONE_RPC_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.DRONE_RPC_SECRET.secretName }}
key: {{ .Values.secrets.DRONE_RPC_SECRET.key }}
- name: DRONE_SERVER_HOST
value: "{{ .Values.env.server.host }}"
- name: DRONE_SERVER_PROTO
value: "{{ .Values.env.server.proto }}"
volumeMounts:
- name: drone-data
mountPath: /data
containers:
- name: drone-runner
image: "{{ .Values.image.runner.repository }}:{{ .Values.image.runner.tag }}"
env:
- name: DRONE_RPC_SERVER
value: "http://localhost:80"
- name: DRONE_RPC_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.DRONE_RPC_SECRET.secretName }}
key: {{ .Values.secrets.DRONE_RPC_SECRET.key }}
- name: DRONE_RPC_HOST
value: "localhost:80"
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: drone-data
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: drone-data
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: drone-data
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: ersatztv
description: A Helm chart for Ersatztv
type: application
version: 0.1.0
appVersion: "25.2.0"

View File

@@ -0,0 +1,33 @@
name: ersatztv
namespace: default
image:
repository: jasongdove/ersatztv
tag: v25.2.0
hwAccl:
enabled: true
nodeAffinity:
key: gpu
value: intel
securityContext:
supplementalGroups:
- 128
- 226
- 106
persistence:
enabled: true
exsistingClaim: true
claimName: longhorn-ersatztv
library:
enabled: true
server: 10.0.0.123
path: /merge
service:
type: LoadBalancer
port: 8409

View File

@@ -0,0 +1,16 @@
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "NodePort" }}
type: NodePort
{{- else if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- protocol: TCP
targetPort: 8409
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,80 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
{{- if .Values.hwAccl.enabled }}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: {{ .Values.nodeAffinity.key }}
operator: In
values:
- "{{ .Values.nodeAffinity.value }}"
supplementalGroups: {{ .Values.securityContext.supplementalGroups | toYaml | nindent 8 }}
{{- end }}
securityContext:
runAsGroup: 0
runAsUser: 0
containers:
- name: {{ .Values.name }}
{{- if .Values.hwAccl.enabled }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}-vaapi"
{{- else }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{- end }}
volumeMounts:
- name: config
mountPath: /root/.local/share/ersatztv
{{- if .Values.hwAccl.enabled }}
- name: intel
mountPath: /dev/dri/renderD128
{{- end }}
- name: transcode
mountPath: /root/.local/share/etv-transcode
- name: content
mountPath: /mnt/merge
securityContext:
privileged: true
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}
- name: transcode
emptyDir: {}
{{- if .Values.hwAccl.enabled }}
- name: intel
hostPath:
path: /dev/dri/renderD128
{{- end }}
{{- if .Values.library.enabled}}
- name: content
nfs:
server: {{ .Values.library.server }}
path: {{ .Values.library.path }}
{{- else }}
- name: content
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: flaresolverr
description: A Helm chart for Flaresolverr
type: application
version: 0.1.0
appVersion: "3.3.25"

View File

@@ -0,0 +1,14 @@
name: flaresolverr
namespace: prod
image:
repository: ghcr.io/flaresolverr/flaresolverr
tag: v3.3.25
env:
LOG_LEVEL: info
TZ: Asia/Kolkata
service:
type: LoadBalancer
port: 8191

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "NodePort" }}
type: NodePort
{{- else if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- protocol: TCP
targetPort: 8191
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,24 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
env:
- name: LOG_LEVEL
value: "{{ .Values.env.LOG_LEVEL }}"
- name: TZ
value: "{{ .Values.env.TZ }}"

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: gitea
description: A Helm chart for Gitea
type: application
version: 0.1.0
appVersion: "1.24.2"

View File

@@ -0,0 +1,39 @@
name: gitea
namespace: prod
image:
app:
repository: gitea/gitea
tag: 1.24.2
db:
repository: postgres
tag: 15.10
env:
USER_UID: 1000
USER_GID: 1000
DB_NAME: gitea
DB_USER: gitea
secrets:
GITEA__database__PASSWD:
name: gitea-db-secret
key: password
persistence:
app:
enabled: true
existingClaim: true
claimName: longhorn-gitea
db:
enabled: true
existingClaim: true
claimName: longhorn-gitea-db
service:
app:
type: LoadBalancer
port: 3111
ssh:
type: LoadBalancer
port: 222

View File

@@ -0,0 +1,51 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Values.name }}-db"
namespace: {{ .Values.namespace }}
spec:
selector:
matchLabels:
app: "{{ .Values.name }}-db"
template:
metadata:
labels:
app: "{{ .Values.name }}-db"
spec:
initContainers:
- name: init-cleanup
image: busybox
command: ["rm", "-rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts:
- name: db
mountPath: /var/lib/postgresql/data
containers:
- name: "{{ .Values.name }}-db"
image: "{{ .Values.image.db.repository }}:{{ .Values.image.db.tag }}"
env:
- name: POSTGRES_USER
value: "{{ .Values.env.DB_USER }}"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.GITEA__database__PASSWD.name }}
key: {{ .Values.secrets.GITEA__database__PASSWD.key }}
- name: POSTGRES_DB
value: "{{ .Values.env.DB_NAME }}"
volumeMounts:
- name: db
mountPath: /var/lib/postgresql/data
volumes:
{{- if and .Values.persistence.db.enabled .Values.persistence.db.existingClaim }}
- name: db
persistentVolumeClaim:
claimName: "{{ .Values.persistence.db.claimName }}"
{{- else if .Values.persistence.db.enabled }}
- name: db
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}-db"
{{- else }}
- name: db
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,35 @@
---
{{- if Values.persistence.app.enabled }}
{{- if not Values.persistence.app.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.app.size }}
{{- end }}
{{- end }}
---
{{- if Values.persistence.db.enabled }}
{{- if not Values.persistence.db.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}-db"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.db.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,72 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if .Values.service.app.type "LoadBalancer" }}
type: LoadBalancer
{{- else if .Values.service.app.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: "{{ .Values.name }}-app"
ports:
- targetPort: 3000
protocol: TCP
{{- if .Values.service.app.type "LoadBalancer" }}
port: {{ .Values.service.app.port }}
{{- else if .Values.service.app.type "NodePort" }}
nodePort: {{ .Values.service.app.nodePort }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-ssh-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.ssh.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.ssh.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: "{{ .Values.name }}-app"
ports:
- targetPort: 22
{{- if eq .Values.service.ssh.type "LoadBalancer" }}
port: {{ .Values.service.ssh.port }}
{{- else if eq .Values.service.ssh.type "NodePort" }}
nodePort: {{ .Values.service.ssh.nodePort }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-int-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: "{{ .Values.name }}-app"
ports:
- protocol: TCP
port: 3000
targetPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-db-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: "{{ .Values.name }}-db"
ports:
- protocol: TCP
port: 5432
targetPort: 5432

View File

@@ -0,0 +1,77 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Values.name }}-app"
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: "{{ .Values.name }}-app"
template:
metadata:
labels:
app: "{{ .Values.name }}-app"
spec:
initContainers:
- name: wait-for-db
image: busybox
command:
- sh
- -c
- |
until nc -z -v -w30 "{{ .Values.name }}-db-service" 5432; do
echo "Waiting for psql database to be ready"
sleep 2
done
containers:
- name: "{{ .Values.name }}-app"
image: "{{ .Values.image.app.repository }}:{{ .Values.image.app.tag }}"
env:
- name: USER_UID
value: "{{ .Values.env.USER_UID }}"
- name: USER_GID
value: "{{ .Values.env.USER_GID }}"
- name: GITEA__database__DB_TYPE
value: "postgres"
- name: GITEA__database__HOST
value: "{{ .Values.name }}-db-service:5432"
- name: GITEA__database__NAME
value: "{{ .Values.env.DB_NAME }}"
- name: GITEA__database__USER
value: "{{ .Values.env.DB_USER }}"
- name: GITEA__database__PASSWD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.GITEA__database__PASSWD.name }}
key: {{ .Values.secrets.GITEA__database__PASSWD.key }}
volumeMounts:
- name: config
mountPath: /data
subPath: gitea-data
- name: timezone
mountPath: /etc/timezone
- name: localtime
mountPath: /etc/localtime
volumes:
- name: timezone
hostPath:
path: /etc/timezone
type: File
- name: localtime
hostPath:
path: /etc/localtime
type: File
{{- if and .Values.persistence.app.enabled .Values.persistence.app.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.app.claimName }}"
{{- else if .Values.persistence.app.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: homepage
description: A Helm chart for Homepage
type: application
version: 0.1.0
appVersion: "1.3.2"

View File

@@ -0,0 +1,18 @@
name: homepage
namespace: prod
image:
repository: ghcr.io/gethomepage/homepage
tag: v1.3.2
secrets:
api-secrets: homepage-secrets
customImagesDirectory:
enabled: true
existingClaim: true
claimName: longhorn-homepage
service:
type: LoadBalancer
port: 30001

View File

@@ -0,0 +1,62 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ .Values.name }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
rules:
- apiGroups:
- ""
resources:
- namespaces
- pods
- nodes
verbs:
- get
- list
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- apiGroups:
- traefik.io
resources:
- ingressroutes
verbs:
- get
- list
- apiGroups:
- gateway.networking.k8s.io
resources:
- httproutes
- gateways
verbs:
- get
- list
- apiGroups:
- metrics.k8s.io
resources:
- nodes
- pods
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Values.name }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.name }}
subjects:
- kind: ServiceAccount
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}

View File

@@ -0,0 +1,315 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/name: "{{ .Values.name }}-config"
data:
docker.yaml: ""
bookmarks.yaml: ""
kubernetes.yaml: |
mode: cluster
widgets.yaml: |
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: true
label: "cluster"
nodes:
show: true
cpu: true
memory: true
showLabel: true
- search:
provider: google
target: _blank
settings.yaml: |
layout:
Proxmox (NVIDIA GPU):
style: row
columns: 5
tab: Stats
Proxmox (AMD GPU):
style: row
columns: 5
tab: Stats
Proxmox (Asus):
style: row
columns: 5
tab: Stats
Apps:
style: row
columns: 4
tab: Apps
Bookmarks:
style: row
columns: 5
tab: Bookmarks
useEqualHeights: true
hideErrors: true
background: /images/background.png
services.yaml: |
- Apps:
- Sonarr:
href: https://sonarr.akshun-lab.uk
description: series
icon: sonarr.png
widget:
type: sonarr
url: http://10.0.0.14:8989
key: "${SONARR_API_KEY}"
- Radarr:
href: https://radarr.akshun-lab.uk
description: movies
icon: radarr.png
widget:
type: radarr
url: http://10.0.0.14:7878
key: "${RADARR_API_KEY}"
- Bazarr:
href: https://bazarr.akshun-lab.uk
description: subtitles
icon: bazarr.png
widget:
type: bazarr
url: http://10.0.0.14:6767
key: "${BAZARR_API_KEY}"
- Jellyfin:
href: https://jellyfin.akshun-lab.uk
description: streaming
icon: jellyfin.png
widget:
type: jellyfin
url: http://10.0.0.14:8096
key: "${JELLYFIN_API_KEY}"
- qBittorrent:
href: https://qbittorrent.akshun-lab.uk
description: torrent client
icon: qbittorrent.png
widget:
type: qbittorrent
username: admin
password: "${QBITTORRENT_PASSWORD}"
url: http://10.0.0.14:8080
- Jellyseerr:
href: https://jellyseerr.akshun-lab.uk
description: request movies and shows
icon: jellyseerr.png
widget:
type: jellyseerr
url: http://10.0.0.14:5055
key: "${JELLYSEERR_API_KEY}"
- Prowlarr:
href: https://prowlarr.akshun-lab.uk
description: indexers
icon: prowlarr.png
widget:
type: prowlarr
url: http://10.0.0.14:9696
key: "${PROWLARR_API_KEY}"
- Speedtest:
href: https://speedtest.akshun-lab.uk
description: speedtest
icon: si-speedtest.svg
widget:
type: speedtest
url: http://10.0.0.14:8181
- Immich:
href: https://immich.akshun-lab.uk
description: photos
icon: immich.png
widget:
type: immich
url: http://10.0.0.14:2283
key: "${IMMICH_API_KEY}"
version: 2
- Proxmox:
href: https://proxmox.akshun-lab.uk
description: VMs
icon: proxmox.png
widget:
type: proxmox
url: https://10.0.0.100:8006
username: api@pam!homepage
password: "${PROXMOX_PASSWORD}"
- Gitea:
href: https://gitea.akshun-lab.uk
description: Git Server
icon: gitea.png
widget:
type: gitea
url: http://10.0.0.14:3011
key: "${GITEA_API_KEY}"
fields: ["repositories", "issues", "pulls"]
- Crafty:
href: https://minecraft.akshun-lab.uk
description: crafty controller
icon: crafty-controller.png
widget:
type: minecraft
url: udp://192.168.1.3:25565
- Invidious:
href: https://invidious.akshun-lab.uk
description: youtube frontend
icon: invidious.png
- Nextcloud:
href: https://nextcloud.akshun-lab.uk
description: files
icon: nextcloud.png
- VS Code:
href: https://vs.akshun-lab.uk
description: VS code server
icon: vscode.png
- Semaphore:
href: https://semaphore.akshun-lab.uk
description: ansible gui
icon: semaphore.png
- Open Media Vault:
href: https://omv.akshun-lab.uk
description: NAS
icon: openmediavault.png
- Ersatztv:
icon: ersatztv.png
description: live tv for jellyfin
href: https://ersatztv.akshun-lab.uk
- Jellystat:
icon: jellystat.png
description: jellyfin stats
href: https://jellystat.akshun-lab.uk
- Paperless NGX:
icon: paperless.png
description: documents OCR
href: https://ngx.akshun-lab.uk
- Longhorn:
icon: longhorn.png
description: kubernetes storage
href: https://longhorn.akshun-lab.uk
- Portainer:
icon: portainer.png
description: container management
href: https://portainer.akshun-lab.uk
- Rancher:
icon: rancher.png
description: kubernetes management
href: https://rancher.akshun-lab.uk
- Open-WebUI:
icon: ollama.png
description: ollama Frontend
href: https://ollama.akshun-lab.uk
- Ghostfolio:
icon: ghostfolio.png
description: portfolio analyzer
href: https://ghost.akshun-lab.uk
- AdGuardHome:
icon: adguard-home.png
description: ad blocker
href: https://adguard.akshun-lab.uk
- Drone:
icon: drone.png
description: CI/CD
href: https://drone.akshun-lab.uk
- Bookmarks:
- Disney:
href: https://www.hotstar.com
- Prime Video:
href: https://primevideo.com
- AngelOne:
href: https://www.angelone.in/trade/watchlist/chart
- MoneyControl:
href: https://moneycontrol.com
- SBI Netbanking:
href: https://retail.onlinesbi.sbi/retail/login.htm
- GW2 Wiki:
href: https://wiki.guildwars2.com/wiki/Event_timers
- GW2 Efficiency:
href: https://gw2efficiency.com
- Youtube:
href: https://youtube.com
- Reddit:
href: https://reddit.com
- Github:
href: https://github.com
- Twitch:
href: https://twitch.tv
- Proxmox (AMD GPU):
- CPU Usage:
widget:
type: glances
url: http://192.168.1.113:61208
metric: cpu
- Memory Usage:
widget:
type: glances
url: http://192.168.1.113:61208
metric: memory
- Processes:
widget:
type: glances
url: http://192.168.1.113:61208
metric: process
- Sensor:
widget:
type: glances
url: http://192.168.1.113:61208
metric: sensor:Tctl
- Disk Usage:
widget:
type: glances
url: http://192.168.1.113:61208
metric: disk:sdb
- Proxmox (NVIDIA GPU):
- CPU Usage:
widget:
type: glances
url: http://192.168.1.126:61208
metric: cpu
- Memory Usage:
widget:
type: glances
url: http://192.168.1.126:61208
metric: memory
- Processes:
widget:
type: glances
url: http://192.168.1.126:61208
metric: process
- Sensor:
widget:
type: glances
url: http://192.168.1.126:61208
metric: sensor:Package id 0
- Disk Usage:
widget:
type: glances
url: http://192.168.1.126:61208
metric: disk:nvme0n1
- Proxmox (Asus):
- CPU Usage:
widget:
type: glances
url: http://192.168.1.199:61208
metric: cpu
- Memory Usage:
widget:
type: glances
url: http://192.168.1.199:61208
metric: memory
- Processes:
widget:
type: glances
url: http://192.168.1.199:61208
metric: process
- Sensor:
widget:
type: glances
url: http://192.168.1.199:61208
metric: sensor:Sensor 1
- Disk Usage:
widget:
type: glances
url: http://192.168.1.199:61208
metric: disk:nvme0n1

View File

@@ -0,0 +1,17 @@
---
{{- if .Values.persistence.enabled }}
{{- if not .Values.customImagesDirectory.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}-images"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,11 @@
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
annotations:
kubernetes.io/service-account.name: {{ .Values.name }}

View File

@@ -0,0 +1,10 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
secrets:
- name: {{ .Values.name }}

View File

@@ -0,0 +1,21 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app.kubernetes.io/name: {{ .Values.name }}
ports:
- targetPort: 3000
{{- if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- else if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}

View File

@@ -0,0 +1,98 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/name: {{ .Values.name }}
spec:
revisionHistoryLimit: 3
replicas: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: {{ .Values.name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Values.name }}
spec:
serviceAccountName: {{ .Values.name }}
automountServiceAccountToken: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
initContainers:
- name: substitute-config
image: alpine
envFrom:
- secretRef:
name: {{ .Values.secrets.api-secrets }}
command:
- "sh"
- "-c"
- apk add gettext && envsubst < /mnt/init/services.yaml > /mnt/services.yaml
volumeMounts:
- name: homepage-config
mountPath: /mnt/init/services.yaml
subPath: services.yaml
- name: tmp
mountPath: /mnt
subPath: services.yaml
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: "{{ .Values.env.HOMEPAGE_ALLOWED_HOSTS }}"
volumeMounts:
- mountPath: /app/config/custom.js
name: homepage-config
subPath: custom.js
- mountPath: /app/config/custom.css
name: homepage-config
subPath: custom.css
- mountPath: /app/config/bookmarks.yaml
name: homepage-config
subPath: bookmarks.yaml
- mountPath: /app/config/docker.yaml
name: homepage-config
subPath: docker.yaml
- mountPath: /app/config/kubernetes.yaml
name: homepage-config
subPath: kubernetes.yaml
- mountPath: /app/config
name: tmp
subPath: services.yaml
- mountPath: /app/config/settings.yaml
name: homepage-config
subPath: settings.yaml
- mountPath: /app/config/widgets.yaml
name: homepage-config
subPath: widgets.yaml
- mountPath: /app/config/logs
name: logs
- mountPath: /app/public/images
name: images
volumes:
- name: homepage-config
configMap:
name: {{ .Values.name }}-config
- name: logs
emptyDir: {}
- name: tmp
emptyDir: {}
{{- if and .Values.customImagesDirectory.enabled .Values.customImagesDirectory.existingClaim }}
- name: images
persistentVolumeClaim:
claimName: {{ .Values.customImagesDirectory.claimName }}
{{- else if .Values.customImagesDirectory.enabled }}
- name: images
persistentVolumeClaim:
claimName: longhorn-{{ .Values.name }}-images
{{- else }}
- name: images
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: immich
description: A Helm chart for Immich
type: application
version: 0.1.0
appVersion: "1.135.3"

View File

@@ -0,0 +1,53 @@
name: immich
namespace: prod
image:
app:
repository: ghcr.io/immich-app/immich-server
tag: v1.135.3
ml:
repository: ghcr.io/immich-app/immich-machine-learning
tag: v1.135.3
hwAccl:
enabled: true
type: nvidia
nodeAffinity:
key: gpu
value: nvidia
env:
TZ: Asia/Kolkata
DB_USERNAME: postgres
DB_DATABASE_NAME: immich
persistence:
modelCache:
enabled: true
existingClaim: true
claimName: longhorn-immich-cache
pictures:
enabled: true
existingClaim: true
claimName: immich-pictures-pvc
db:
enabled: true
nfs:
server: 10.0.0.10
path: /home/akshun/immich-data
secret:
name: immich-postgres-secret
dbPasswordKey: password
service:
app:
type: LoadBalancer
port: 2283
ml:
type: LoadBalancer
port: 3333

View File

@@ -0,0 +1,43 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Values.name }}-db"
namespace: {{ .Values.namespace }}
spec:
selector:
matchLabels:
app: "{{ .Values.name }}-db"
template:
metadata:
labels:
app: "{{ .Values.name }}-db"
spec:
containers:
- name: redis
image: docker.io/valkey/valkey:8-bookworm@sha256:fec42f399876eb6faf9e008570597741c87ff7662a54185593e74b09ce83d177
env:
- name: REDIS_HOSTNAME
value: "{{ .Values.name }}-redis-service"
- name: immich-psql
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secret.name }}
key: {{ .Values.secret.dbPasswordKey }}
- name: POSTGRES_USER
value: "{{ .Values.env.DB_USERNAME }}"
- name: POSTGRES_DB
value: "{{ .Values.env.DB_DATABASE_NAME }}"
- name: POSTGRES_INITDB_ARGS
value: "--data-checksums"
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: immich
volumes:
- name: immich
nfs:
server: {{ .Values.persistence.db.nfs.server }}
path: {{ .Values.persistence.db.nfs.path }}

View File

@@ -0,0 +1,32 @@
---
{{- if .Values.persistence.pictures.enabled }}
{{- if not .Values.persistence.pictures.existingClaim }}
{{- if eq .Values.persistence.pictures.type "smb" }}
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: smb.csi.k8s.io
name: "{{ .Values.name }}-pictures-pv"
namespace: {{ .Values.namespace }}
spec:
capacity:
storage: {{ .Values.persistence.pictures.size }}
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: "{{ .Values.name }}-pictures-pv"
mountOptions:
- dir_mode=0777
- file_mode=0777
csi:
driver: smb.csi.k8s.io
volumeHandle: "{{ .Values.persistence.pictures.smb.server }}#pictures#immich"
volumeAttributes:
source: "//{{ .Values.persistence.pictures.smb.server }}/pictures"
nodeStageSecretRef:
name: {{ .Values.persistence.pictures.smb.secretName }}
namespace: {{ .Values.namespace }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,37 @@
---
{{- if .Values.persistence.modelCache.enabled }}
{{- if not .Values.persistence.modelCache.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}-cache"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.modelCache.size }}
{{- end }}
{{- end }}
---
{{- if .Values.persistence.pictures.enabled }}
{{- if not .Values.persistence.pictures.existingClaim }}
{{- if eq .Values.persistence.pictures.type "smb" }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ .Values.name }}-pictures-pvc"
namespace: {{ .Values.namespace }}
spec:
storageClassName: "{{ .Values.name }}-pictures-pv"
accessModes:
- ReadWriteMany
resources:
requests:
storage: {{ .Values.persistence.pictures.size }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,71 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.app.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.app.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: "{{ .Values.name }}-app"
ports:
- targetPort: 2283
{{- if eq .Values.service.app.type "LoadBalancer" }}
port: {{ .Values.service.app.port }}
{{- else if eq .Values.service.app.type "NodePort" }}
nodePort: {{ .Values.service.app.nodePort }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-machine-learning-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.ml.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.ml.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: "{{ .Values.name }}-app"
ports:
- targetPort: 3003
{{- if eq .Values.service.ml.type "LoadBalancer" }}
port: {{ .Values.service.ml.port }}
{{- else if eq .Values.service.ml.type "NodePort" }}
nodePort: {{ .Values.service.ml.nodePort }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-psql-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: "{{ .Values.name }}-db"
ports:
- protocol: TCP
port: 5432
targetPort: 5432
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-redis-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: "{{ .Values.name }}-db"
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@@ -0,0 +1,139 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Values.name }}-app"
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: "{{ .Values.name }}-app"
template:
metadata:
labels:
app: "{{ .Values.name }}-app"
spec:
{{- if .Values.hwAccl.enabled }}
{{- if eq .Values.hwAccl.type "nvidia" }}
runtimeClassName: nvidia
{{- else if eq .Values.hwAccl.type "intel" }}
supplementalGroups: {{ .Values.securityContext.supplementalGroups | toYaml | nindent 8 }}
{{- end }}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: {{ .Values.nodeAffinity.key }}
operator: In
values:
- "{{ .Values.nodeAffinity.value }}"
{{- end }}
initContainers:
- name: wait-for-redis
image: busybox
command:
- sh
- -c
- |
until nc -z -v -w30 "{{ .Values.name }}-redis-service" 6379; do
echo "Waiting for redis database to be ready..."
sleep 2
done
- name: wait-for-psql
image: busybox
command:
- sh
- -c
- |
until nc -z -v -w30 "{{ .Values.name }}-psql-service" 5432; do
echo "Waiting for psql database to be ready"
sleep 2
done
containers:
- name: "{{ .Values.name }}-server"
image: "{{ .Values.image.app.repository }}:{{ .Values.image.app.tag }}"
env:
- name: TZ
value: "{{ .Values.env.TZ }}"
- name: REDIS_HOSTNAME
value: "{{ .Values.name }}-redis-service"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secret.name }}
key: {{ .Values.secret.dbPasswordKey }}
- name: DB_USERNAME
value: "{{ .Values.env.DB_USERNAME }}"
- name: DB_DATABASE_NAME
value: "{{ .Values.env.DB_DATABASE_NAME }}"
- name: DB_HOSTNAME
value: "{{ .Values.name }}-psql-service"
volumeMounts:
- mountPath: /usr/src/app/upload
name: pictures
- name: immich-machine-learning
{{- if .Values.hwAccl.enabled }}
{{- if eq .Values.hwAccl.type "nvidia" }}
image: "{{ .Values.image.ml.repository }}:{{ .Values.image.ml.tag }}-cuda"
{{- else if eq .Values.hwAccl.type "intel" }}
image: "{{ .Values.image.ml.repository }}:{{ .Values.image.ml.tag }}-openvino"
{{- end }}
{{- else }}
image: "{{ .Values.image.ml.repository }}:{{ .Values.image.ml.tag }}"
{{- end }}
env:
- name: REDIS_HOSTNAME
value: "{{ .Values.name }}-redis-service"
{{- if .Values.hwAccl.enabled }}
{{- if eq .Values.hwAccl.type "nvidia" }}
- name: NVIDIA_VISIBLE_DEVICES
value: "all"
{{- end }}
{{- end }}
- name: MACHINE_LEARNING_DEVICE_IDS
value: "0"
volumeMounts:
- name: model-cache
mountPath: /cache
{{- if .Values.hwAccl.enabled }}
{{- if eq .Values.hwAccl.type "intel" }}
- name: intel
mountPath: /dev/dri/
{{- end }}
{{- end }}
volumes:
{{- if .Values.persistence.pictures.enabled }}
{{- if eq .Values.persistence.pictures.type "nfs" }}
- name: pictures
nfs:
server: {{ .Values.persistence.pictures.nfs.server }}
path: {{ .Values.persistence.pictures.nfs.path }}
{{- else if eq .Values.persistence.pictures.type "smb" }}
- name: pictures
persistentVolumeClaim:
claimName: {{ .Values.name }}-pictures-pvc
{{- else if .Values.persistence.pictures.existingClaim }}
- name: pictures
persistentVolumeClaim:
claimName: {{ .Values.persistence.pictures.claimName }}
{{- end }}
{{- else }}
- name: pictures
emptyDir: {}
{{- end }}
{{- if .Values.persistence.modelCache.enabled }}
{{- if .Values.persistence.modelCache.existingClaim }}
- name: model-cache
persistentVolumeClaim:
claimName: {{ .Values.persistence.modelCache.claimName }}
{{- else }}
- name: model-cache
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}-cache"
{{- end }}
{{- else }}
- name: model-cache
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: invidious
description: A Helm chart for Invidious
type: application
version: 0.1.0
appVersion: "0.1.0"

View File

@@ -0,0 +1,29 @@
name: invidious
namespace: default
image:
app:
repository: quay.io/invidious/invidious
tag: sha256:9ffa4f1ea5cf01abe3102777102bd7a13153c79f6ff6ac072b6a29dda6909a8b
db:
repository: postgres
tag: "15.13"
signatureHelper:
repository: quay.io/invidious/inv-sig-helper
tag: sha256:b5466c9add729e82e4e3ee5515c30b69df02d78ebb2486dbc9c63e456f29083d
service:
type: LoadBalancer
port: 3111
secrets:
configSecretName: invidious-secrets
dbName:
Name: invdious-db-secrets
Key: postgres-db
dbUser:
User: invdious-db-secrets
Key: postgres-user
dbPassword:
Password: invdious-db-secrets
Key: postgres-password

View File

@@ -0,0 +1,20 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ .Values.name }}-config"
namespace: default
data:
invidious.yml: |
db:
dbname: invidious
user: kemal
password: ${INVIDIOUS_DB_PASSWORD}
host: localhost
port: 5432
check_tables: true
signature_server: localhost:12999
visitor_data: ${VISITOR_DATA}
po_token: ${PO_TOKEN}
port: 3000
hmac_key: ${INVIDIOUS_HMAC_KEY}

View File

@@ -0,0 +1,17 @@
---
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}-config"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- targetPort: 3000
protocol: TCP
{{- if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- else if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}

View File

@@ -0,0 +1,115 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
initContainers:
- name: substitute-config
image: alpine
envFrom:
- secretRef:
name: {{ .Values.secrets.configSecretName }}
command:
- sh
- -c
- apk add gettext && envsubst < /mnt/init/invidious.yml > /mnt/invidious.yml
volumeMounts:
- name: "{{ .Values.name }}-config"
mountPath: /mnt/init/invidious.yml
subPath: invidious.yml
- name: tmp
mountPath: /mnt
subPath: invidious.yml
- name: clean-db-dir
image: busybox
command:
- sh
- -c
- |
rm -rf /var/lib/postgresql/data/lost+found
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: postgres
image: "{{ .Values.image.db.repository }}:{{ .Values.image.db.tag }}"
restartPolicy: Always
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.dbName.Name }}
key: {{ .Values.secrets.dbName.Key }}
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.dbUser.User }}
key: {{ .Values.secrets.dbUser.Key }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.dbPassword.Password }}
key: {{ .Values.secrets.dbPassword.Key }}
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: inv-sig-helper
image: "{{ .Values.image.signatureHelper.repository }}@{{ .Values.image.signatureHelper.tag }}"
restartPolicy: Always
args: ["--tcp", "0.0.0.0:12999"]
env:
- name: RUST_LOG
value: "info"
securityContext:
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
containers:
- name: invidious
image: "{{ .Values.image.app.repository }}@{{ .Values.image.app.tag }}"
command:
- sh
- -c
- |
export INVIDIOUS_CONFIG="$(cat /mnt/invidious.yml)" &&
exec /invidious/invidious
env:
- name: INVIDIOUS_PORT
value: "3000"
volumeMounts:
- name: logging
mountPath: /var/log/invidious
- name: tmp
mountPath: /mnt
subPath: invidious.yml
volumes:
- name: logging
emptyDir: {}
- name: tmp
emptyDir: {}
- name: invidious-config
configMap:
name: "{{ .Values.name }}-config"
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: postgres-data
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: postgres-data
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}-config"
{{- else }}
- name: postgres-data
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: jellyfin
description: A Helm chart for Jellyfin
type: application
version: 0.1.0
appVersion: "10.10.7"

View File

@@ -0,0 +1,26 @@
name: jellyfin
namespace: prod
image:
repository: jellyfin/jellyfin
tag: 10.10.7
nodeSelector:
enabled: true
key: kubernetes.io/hostname
value: master-4
persistence:
config:
enabled: true
existingClaim: true
claimName: longhorn-jellyfin-config
media:
nfs:
server: 10.0.0.123
path: /merge
service:
type: LoadBalancer
port: 8096

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
selector:
app: {{ .Values.name }}
ports:
- targetPort: 8096
protocol: TCP
{{- if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- else if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}

View File

@@ -0,0 +1,67 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
securityContext:
supplementalGroups:
- 128
- 226
- 106
- 44
- 104
{{- if .Values.nodeSelector.enabled }}
nodeSelector:
{{ .Values.nodeSelector.key }}: {{ .Values.nodeSelector.value }}
{{- end }}
containers:
- name: jellyfin
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
volumeMounts:
- name: media
mountPath: /media
readOnly: true
recursiveReadOnly: Enabled
- name: config
mountPath: /config
- name: cache
mountPath: /cache
- name: card
mountPath: /dev/dri/renderD128
securityContext:
privileged: true
volumes:
{{- if and .Values.persistence.config.enabled .Values.persistence.config.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.config.claimName }}"
{{- else if .Values.persistence.config.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}-config"
{{- else }}
- name: config
emptyDir: {}
{{- end }}
- name: cache
hostPath:
path: /home/akshun/jellyfin/cache
type: Directory
- name: media
nfs:
server: {{ .Values.persistence.media.nfs.server }}
path: {{ .Values.persistence.media.nfs.path }}
- name: card
hostPath:
path: /dev/dri/renderD128

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: jellyseerr
description: A Helm chart for Jellyseerr
type: application
version: 0.1.0
appVersion: "2.7.0"

View File

@@ -0,0 +1,19 @@
name: jellyseerr
namespace: prod
image:
repository: jellyseerr/jellyseerr
tag: 2.7.0
env:
LOG_LEVEL: info
timezone: "Asia/Kolkata"
persistence:
enabled: true
existingClaim: true
claimName: "longhorn-jellyseerr"
service:
type: LoadBalancer
port: 5055

View File

@@ -0,0 +1,17 @@
---
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: {{ .Values.name }}
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
ports:
- targetPort: 5055
protocol: TCP
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,40 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
env:
- name: LOG_LEVEL
value: "{{ .Values.env.LOG_LEVEL }}"
- name: TZ
value: "{{ .Values.env.timezone }}"
volumeMounts:
- name: config
mountPath: /app/config
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: jellystat
description: A Helm chart for Jellystat
type: application
version: 0.1.0
appVersion: "1.1.6"

View File

@@ -0,0 +1,27 @@
name: jellystat
namespace: prod
image:
repository: cyfershepard/jellystat
tag: "1.1.6"
env:
dbName: jfstat
dbUser: postgres
secrets:
db:
secretName: jellystat-secret
secretKey: password
jwt:
secretName: jellystat-secret
secretKey: jwt
persistence:
enabled: true
existingClaim: true
claimName: longhorn-jellystat-data
service:
type: LoadBalancer
port: 3001

View File

@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "longhorn-{{ .Values.name }}"
namespace: {{ .Values.namespace }}
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: {{ .Values.persistence.size }}

View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.name }}-service"
namespace: {{ .Values.namespace }}
spec:
selector:
app: {{ .Values.name }}
{{- if eq .Values.service.type "LoadBalancer" }}
type: LoadBalancer
{{- else if eq .Values.service.type "NodePort" }}
type: NodePort
{{- end }}
ports:
- targetPort: 3000
protocol: TCP
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "LoadBalancer" }}
port: {{ .Values.service.port }}
{{- end }}

View File

@@ -0,0 +1,78 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
initContainers:
- name: init-cleanup
image: busybox
command: ["rm", "-rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts:
- name: backup
mountPath: /var/lib/postgresql/data
- name: "{{ .Values.name }}-db"
image: postgres:alpine
restartPolicy: Always
env:
- name: POSTGRES_DB
value: "{{ .Values.env.dbName }}"
- name: POSTGRES_USER
value: "{{ .Values.env.dbUser }}"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.db.secretName }}
key: {{ .Values.secrets.db.secretKey }}
volumeMounts:
- name: config
mountPath: /var/lib/postgresql/data
subPath: pgdata
containers:
- name: {{ .Values.name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
env:
- name: POSTGRES_USER
value: "{{ .Values.env.dbUser }}"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.db.secretName }}
key: {{ .Values.secrets.db.secretKey }}
- name: POSTGRES_IP
value: "localhost"
- name: POSTGRES_PORT
value: "5432"
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.secrets.jwt.secretName }}
key:
- name: POSTGRES_DB
value: "{{ .Values.env.dbName }}"
volumeMounts:
- name: config
mountPath: /app/backend/backup-data
subPath: backup
volumes:
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}
- name: config
persistentVolumeClaim:
claimName: "{{ .Values.persistence.claimName }}"
{{- else if .Values.persistence.enabled }}
- name: config
persistentVolumeClaim:
claimName: "longhorn-{{ .Values.name }}"
{{- else }}
- name: config
emptyDir: {}
{{- end }}