diff --git a/clusters/cl01tl/applications/homepage/values.yaml b/clusters/cl01tl/applications/homepage/values.yaml index 70e25d813..3405ba69c 100644 --- a/clusters/cl01tl/applications/homepage/values.yaml +++ b/clusters/cl01tl/applications/homepage/values.yaml @@ -567,6 +567,12 @@ homepage: href: https://calibre-downloader-cl01tl.boreal-beaufort.ts.net siteMonitor: http://calibre-web-automated-downloader.calibre-web-automated:8084 statusStyle: dot + - Jellyplist: + icon: sh-jellyfin.png + description: Spotify to Jellyfin Playlist Manager + href: https://jellyplist-cl01tl.boreal-beaufort.ts.net + siteMonitor: http://jellyplist.jellyplist:5055 + statusStyle: dot - Tdarr: icon: sh-tdarr.png description: Media transcoding and health checks diff --git a/clusters/cl01tl/applications/jellyplist/Chart.yaml b/clusters/cl01tl/applications/jellyplist/Chart.yaml new file mode 100644 index 000000000..0c82838e2 --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/Chart.yaml @@ -0,0 +1,32 @@ +apiVersion: v2 +name: jellyplist +version: 1.0.0 +description: Jellyplist +keywords: + - Jellyplist + - jellyfin +home: https://wiki.alexlebens.dev/doc/jellyplist-LnO1zUKXaD +sources: + - https://github.com/kamilkosek/jellyplist + - https://github.com/valkey-io/valkey + - https://github.com/cloudnative-pg/cloudnative-pg + - https://github.com/kamilkosek/jellyplist/pkgs/container/jellyplist + - https://github.com/bjw-s/helm-charts/tree/main/charts/other/app-template + - https://github.com/bitnami/charts/tree/main/bitnami/valkey + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +maintainers: + - name: alexlebens +dependencies: + - name: app-template + alias: jellyplist + repository: https://bjw-s.github.io/helm-charts/ + version: 3.7.1 + - name: valkey + version: 2.4.1 + repository: https://charts.bitnami.com/bitnami + - name: postgres-cluster + alias: postgres-17-cluster + version: 4.2.0 + repository: http://alexlebens.github.io/helm-charts +icon: https://raw.githubusercontent.com/kamilkosek/jellyplist/main/static/images/logo_large.png +appVersion: v0.1.9 diff --git a/clusters/cl01tl/applications/jellyplist/templates/external-secret.yaml b/clusters/cl01tl/applications/jellyplist/templates/external-secret.yaml new file mode 100644 index 000000000..15715c817 --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/templates/external-secret.yaml @@ -0,0 +1,83 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: jellyplist-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jellyplist-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret-key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/jellyplist/config + metadataPolicy: None + property: secret-key + - secretKey: spotify-client-id + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/jellyplist/config + metadataPolicy: None + property: spotify-client-id + - secretKey: spotify-client-secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/jellyplist/config + metadataPolicy: None + property: spotify-client-secret + - secretKey: jellyfin-admin-password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/jellyplist/config + metadataPolicy: None + property: jellyfin-admin-password + - secretKey: lidarr-key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/lidarr2/key + metadataPolicy: None + property: key + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: jellyplist-postgresql-17-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jellyplist-postgresql-17-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: access + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: secret diff --git a/clusters/cl01tl/applications/jellyplist/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/jellyplist/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..f2b33caad --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jellyplist-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jellyplist-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: jellyplist-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/jellyplist/templates/persistent-volume.yaml b/clusters/cl01tl/applications/jellyplist/templates/persistent-volume.yaml new file mode 100644 index 000000000..a614fb060 --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: jellyplist-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jellyplist-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: /volume2/Storage/Music + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/jellyplist/templates/service.yaml b/clusters/cl01tl/applications/jellyplist/templates/service.yaml new file mode 100644 index 000000000..37d365316 --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/templates/service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: redis + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: network + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + internalTrafficPolicy: Cluster + ports: + - name: tcp-redis + nodePort: null + port: 6379 + targetPort: redis + selector: + app.kubernetes.io/component: primary + app.kubernetes.io/instance: jellyplist + app.kubernetes.io/name: valkey + sessionAffinity: None + type: ClusterIP diff --git a/clusters/cl01tl/applications/jellyplist/values.yaml b/clusters/cl01tl/applications/jellyplist/values.yaml new file mode 100644 index 000000000..451ebd8a1 --- /dev/null +++ b/clusters/cl01tl/applications/jellyplist/values.yaml @@ -0,0 +1,144 @@ +jellyplist: + controllers: + main: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + pod: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch + containers: + main: + image: + repository: ghcr.io/kamilkosek/jellyplist + tag: v0.1.10 + pullPolicy: IfNotPresent + env: + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: jellyplist-secret + key: secret-key + - name: JELLYFIN_SERVER_URL + value: http://jellyfin.jellyfin:80 + - name: JELLYFIN_ADMIN_USER + value: jellyplist + - name: JELLYFIN_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: jellyplist-secret + key: jellyfin-admin-password + - name: SPOTIFY_CLIENT_ID + valueFrom: + secretKeyRef: + name: jellyplist-secret + key: spotify-client-id + - name: SPOTIFY_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: jellyplist-secret + key: spotify-client-secret + - name: JELLYPLIST_DB_HOST + valueFrom: + secretKeyRef: + name: jellyplist-postgresql-17-cluster-app + key: host + - name: JELLYPLIST_DB_USER + valueFrom: + secretKeyRef: + name: jellyplist-postgresql-17-cluster-app + key: username + - name: JELLYPLIST_DB_PASSWORD + valueFrom: + secretKeyRef: + name: jellyplist-postgresql-17-cluster-app + key: password + - name: LIDARR_API_KEY + valueFrom: + secretKeyRef: + name: jellyplist-secret + key: lidarr-key + - name: LIDARR_URL + value: http://lidarr2.lidarr2:80 + - name: SPOTIFY_COUNTRY_CODE + value: US + - name: MUSIC_STORAGE_BASE_PATH + value: /mnt/store/Music/ + - name: SPOTDL_OUTPUT_FORMAT + value: "{artist}/{album}/{artist} - {album} - {title}" + - name: REDIS_URL + value: redis://jellyplist-valkey-primary.jellyplist:6379/0 + resources: + requests: + cpu: 100m + memory: 256Mi + serviceAccount: + create: true + service: + main: + controller: main + ports: + http: + port: 5055 + targetPort: 5055 + protocol: HTTP + ingress: + tailscale: + enabled: true + className: tailscale + hosts: + - host: jellyplist-cl01tl + paths: + - path: / + pathType: Prefix + service: + name: jellyplist + port: 5055 + tls: + - hosts: + - jellyplist-cl01tl + persistence: + music: + existingClaim: jellyplist-nfs-storage + advancedMounts: + main: + main: + - path: /mnt/store/Music + readOnly: false +valkey: + architecture: standalone + auth: + enabled: false + usePasswordFiles: false + primary: + persistence: + enabled: false + replica: + persistence: + enabled: false +postgres-17-cluster: + mode: standalone + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + resources: + requests: + memory: 1Gi + cpu: 200m + monitoring: + enabled: true + bootstrap: + initdb: + database: jellyplist + backup: + enabled: true + endpointURL: https://nyc3.digitaloceanspaces.com + destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/jellyplist/jellyplist-postgresql-17-cluster + endpointCredentials: jellyplist-postgresql-17-cluster-backup-secret + backupIndex: 1