From b4e57b4f0c6ad3f31e9058f34d6819d6aaacfce0 Mon Sep 17 00:00:00 2001 From: Shahab Dogar Date: Mon, 24 Nov 2025 12:14:07 +0500 Subject: [PATCH] feat: MediaServices | deploy through cdktf --- main.ts | 5 + media-services/index.ts | 81 ++++++++++ media-services/jellyfin/index.ts | 141 +++++++++++++++++ media-services/prowlarr/index.ts | 107 +++++++++++++ media-services/qbittorrent/index.ts | 150 ++++++++++++++++++ media-services/radarr/index.ts | 145 +++++++++++++++++ media-services/sonarr/index.ts | 145 +++++++++++++++++ media-services/types.ts | 32 ++++ media/deployment.yaml | 231 ---------------------------- media/ingress.yaml | 76 --------- media/namespace.yaml | 5 - media/pvc.yaml | 106 ------------- media/service.yaml | 69 --------- 13 files changed, 806 insertions(+), 487 deletions(-) create mode 100644 media-services/index.ts create mode 100644 media-services/jellyfin/index.ts create mode 100644 media-services/prowlarr/index.ts create mode 100644 media-services/qbittorrent/index.ts create mode 100644 media-services/radarr/index.ts create mode 100644 media-services/sonarr/index.ts create mode 100644 media-services/types.ts delete mode 100644 media/deployment.yaml delete mode 100644 media/ingress.yaml delete mode 100644 media/namespace.yaml delete mode 100644 media/pvc.yaml delete mode 100644 media/service.yaml diff --git a/main.ts b/main.ts index 334a1bf..5339f42 100644 --- a/main.ts +++ b/main.ts @@ -7,6 +7,7 @@ import { K8SOperators } from "./k8s-operators"; import { CoreServices } from "./core-services"; import { NetworkSecurity } from "./network-security"; import { GamingServices } from "./gaming-services/minecraft"; +import { MediaServices } from "./media-services"; import { PKI } from "./pki"; dotenv.config(); @@ -39,6 +40,9 @@ utilityServices.node.addDependency(networkSecurity); const gamingServices = new GamingServices(app, "gaming-services"); gamingServices.node.addDependency(networkSecurity); +const mediaServices = new MediaServices(app, "media-services"); +mediaServices.node.addDependency(networkSecurity); + const caches = new CacheInfrastructure(app, "cache-infrastructure"); caches.node.addDependency(utilityServices); @@ -70,5 +74,6 @@ deploy(networkSecurity, "network-security"); deploy(utilityServices, "utility-services"); deploy(caches, "cache-infrastructure"); deploy(gamingServices, "gaming-services"); +deploy(mediaServices, "media-services"); app.synth(); diff --git a/media-services/index.ts b/media-services/index.ts new file mode 100644 index 0000000..428224f --- /dev/null +++ b/media-services/index.ts @@ -0,0 +1,81 @@ +import { Construct } from "constructs"; +import { TerraformStack } from "cdktf"; +import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; +import { NamespaceV1 } from "@cdktf/provider-kubernetes/lib/namespace-v1"; + +import { LonghornPvc } from "../utils"; +import { JellyfinServer } from "./jellyfin"; +import { SonarrServer } from "./sonarr"; +import { RadarrServer } from "./radarr"; +import { QBittorrentServer } from "./qbittorrent"; +import { ProwlarrServer } from "./prowlarr"; + +export class MediaServices extends TerraformStack { + constructor(scope: Construct, id: string) { + super(scope, id); + + const provider = new KubernetesProvider(this, "kubernetes", { + configPath: "~/.kube/config", + }); + + const namespace = "media"; + + // Create namespace + new NamespaceV1(this, "namespace", { + metadata: { + name: namespace, + }, + }); + + // Shared PVCs + const mediaPvc = new LonghornPvc(this, "media-pvc", { + provider, + name: "media", + namespace, + size: "1Ti", + }); + + const downloadsPvc = new LonghornPvc(this, "downloads-pvc", { + provider, + name: "downloads", + namespace, + size: "450Gi", + }); + + // Deploy media services + new JellyfinServer(this, "jellyfin", { + provider, + namespace, + mediaPvcName: mediaPvc.name, + host: "media.dogar.dev", + }); + + new SonarrServer(this, "sonarr", { + provider, + namespace, + mediaPvcName: mediaPvc.name, + downloadsPvcName: downloadsPvc.name, + host: "sonarr.dogar.dev", + }); + + new RadarrServer(this, "radarr", { + provider, + namespace, + mediaPvcName: mediaPvc.name, + downloadsPvcName: downloadsPvc.name, + host: "radarr.dogar.dev", + }); + + new QBittorrentServer(this, "qbittorrent", { + provider, + namespace, + downloadsPvcName: downloadsPvc.name, + host: "torrent.dogar.dev", + }); + + new ProwlarrServer(this, "prowlarr", { + provider, + namespace, + }); + } +} diff --git a/media-services/jellyfin/index.ts b/media-services/jellyfin/index.ts new file mode 100644 index 0000000..6b9b985 --- /dev/null +++ b/media-services/jellyfin/index.ts @@ -0,0 +1,141 @@ +import { Construct } from "constructs"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; + +import { InternalIngressRoute, LonghornPvc } from "../../utils"; +import { BaseMediaServiceOptions, getAamil3NodeSelector } from "../types"; + +type JellyfinServerOptions = BaseMediaServiceOptions & { + /** Name of the shared media PVC */ + mediaPvcName: string; + /** Hostname for the ingress */ + host: string; +}; + +export class JellyfinServer extends Construct { + constructor(scope: Construct, id: string, options: JellyfinServerOptions) { + super(scope, id); + + const { provider, namespace, mediaPvcName, host } = options; + const name = "server"; + + // Config PVC with backup + const configPvc = new LonghornPvc(this, "config", { + provider, + name: "jellyfin-config", + namespace, + size: "5Gi", + backup: true, + }); + + // Service + new ServiceV1(this, "service", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + app: name, + }, + port: [ + { + name: "http", + port: 80, + targetPort: "8096", + }, + ], + type: "ClusterIP", + }, + }); + + // Deployment + new DeploymentV1(this, "deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + replicas: "1", + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: getAamil3NodeSelector(), + container: [ + { + name, + image: "jellyfin/jellyfin:latest", + imagePullPolicy: "IfNotPresent", + port: [ + { + containerPort: 8096, + name: "http", + }, + ], + env: [ + { + name: "TZ", + value: "Asia/Karachi", + }, + ], + volumeMount: [ + { + name: "config", + mountPath: "/config", + }, + { + name: "cache", + mountPath: "/cache", + }, + { + name: "media", + mountPath: "/media", + }, + ], + }, + ], + volume: [ + { + name: "config", + persistentVolumeClaim: { + claimName: configPvc.name, + }, + }, + { + name: "cache", + emptyDir: {}, + }, + { + name: "media", + persistentVolumeClaim: { + claimName: mediaPvcName, + }, + }, + ], + }, + }, + }, + }); + + // Ingress - using internal ingress for secure access + new InternalIngressRoute(this, "ingress", { + provider, + namespace, + name, + host, + serviceName: name, + servicePort: 80, + }); + } +} diff --git a/media-services/prowlarr/index.ts b/media-services/prowlarr/index.ts new file mode 100644 index 0000000..2955d59 --- /dev/null +++ b/media-services/prowlarr/index.ts @@ -0,0 +1,107 @@ +import { Construct } from "constructs"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; + +import { LonghornPvc } from "../../utils"; +import { + BaseMediaServiceOptions, + getWorkerNodeSelector, + getCommonEnv, +} from "../types"; + +export class ProwlarrServer extends Construct { + constructor(scope: Construct, id: string, options: BaseMediaServiceOptions) { + super(scope, id); + + const { provider, namespace } = options; + const name = "prowlarr"; + + // Config PVC with backup + const configPvc = new LonghornPvc(this, "config", { + provider, + name: "prowlarr-config", + namespace, + size: "512Mi", + backup: true, + }); + + // Service + new ServiceV1(this, "service", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + app: name, + }, + port: [ + { + name: "http", + port: 80, + targetPort: "9696", + }, + ], + type: "ClusterIP", + }, + }); + + // Deployment + new DeploymentV1(this, "deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + replicas: "1", + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: getWorkerNodeSelector(), + container: [ + { + name, + image: "lscr.io/linuxserver/prowlarr:latest", + imagePullPolicy: "IfNotPresent", + port: [ + { + containerPort: 9696, + name: "http", + }, + ], + env: getCommonEnv(), + volumeMount: [ + { + name: "config", + mountPath: "/config", + }, + ], + }, + ], + volume: [ + { + name: "config", + persistentVolumeClaim: { + claimName: configPvc.name, + }, + }, + ], + }, + }, + }, + }); + + // Note: No ingress - Prowlarr is for internal use only + } +} diff --git a/media-services/qbittorrent/index.ts b/media-services/qbittorrent/index.ts new file mode 100644 index 0000000..2fd2f4c --- /dev/null +++ b/media-services/qbittorrent/index.ts @@ -0,0 +1,150 @@ +import { Construct } from "constructs"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; + +import { InternalIngressRoute, LonghornPvc } from "../../utils"; +import { + BaseMediaServiceOptions, + getAamil3NodeSelector, + getCommonEnv, +} from "../types"; + +type QBittorrentServerOptions = BaseMediaServiceOptions & { + /** Name of the shared downloads PVC */ + downloadsPvcName: string; + /** Hostname for the ingress */ + host: string; +}; + +export class QBittorrentServer extends Construct { + constructor( + scope: Construct, + id: string, + options: QBittorrentServerOptions, + ) { + super(scope, id); + + const { provider, namespace, downloadsPvcName, host } = options; + const name = "qbittorrent"; + + // Config PVC with backup + const configPvc = new LonghornPvc(this, "config", { + provider, + name: "qbittorrent-config", + namespace, + size: "512Mi", + backup: true, + }); + + // Service + new ServiceV1(this, "service", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + app: name, + }, + port: [ + { + name: "http", + port: 80, + targetPort: "8080", + }, + ], + type: "ClusterIP", + }, + }); + + // Deployment + new DeploymentV1(this, "deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + replicas: "1", + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: getAamil3NodeSelector(), + container: [ + { + name, + image: "lscr.io/linuxserver/qbittorrent:latest", + port: [ + { + containerPort: 8080, + name: "http", + }, + { + containerPort: 6881, + name: "bt", + }, + { + containerPort: 6881, + protocol: "UDP", + name: "bt-udp", + }, + ], + env: [ + ...getCommonEnv(), + { + name: "WEBUI_PORT", + value: "8080", + }, + ], + volumeMount: [ + { + name: "config", + mountPath: "/config", + }, + { + name: "downloads", + mountPath: "/downloads", + }, + ], + }, + ], + volume: [ + { + name: "config", + persistentVolumeClaim: { + claimName: configPvc.name, + }, + }, + { + name: "downloads", + persistentVolumeClaim: { + claimName: downloadsPvcName, + }, + }, + ], + }, + }, + }, + }); + + // Ingress + new InternalIngressRoute(this, "ingress", { + provider, + namespace, + name, + host, + serviceName: name, + servicePort: 80, + }); + } +} diff --git a/media-services/radarr/index.ts b/media-services/radarr/index.ts new file mode 100644 index 0000000..da139a5 --- /dev/null +++ b/media-services/radarr/index.ts @@ -0,0 +1,145 @@ +import { Construct } from "constructs"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; + +import { InternalIngressRoute, LonghornPvc } from "../../utils"; +import { + BaseMediaServiceOptions, + getAamil3NodeSelector, + getCommonEnv, +} from "../types"; + +type RadarrServerOptions = BaseMediaServiceOptions & { + /** Name of the shared media PVC */ + mediaPvcName: string; + /** Name of the shared downloads PVC */ + downloadsPvcName: string; + /** Hostname for the ingress */ + host: string; +}; + +export class RadarrServer extends Construct { + constructor(scope: Construct, id: string, options: RadarrServerOptions) { + super(scope, id); + + const { provider, namespace, mediaPvcName, downloadsPvcName, host } = + options; + const name = "radarr"; + + // Config PVC with backup + const configPvc = new LonghornPvc(this, "config", { + provider, + name: "radarr-config", + namespace, + size: "512Mi", + backup: true, + }); + + // Service + new ServiceV1(this, "service", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + app: name, + }, + port: [ + { + name: "http", + port: 80, + targetPort: "7878", + }, + ], + type: "ClusterIP", + }, + }); + + // Deployment + new DeploymentV1(this, "deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + replicas: "1", + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: getAamil3NodeSelector(), + container: [ + { + name, + image: "lscr.io/linuxserver/radarr:latest", + imagePullPolicy: "IfNotPresent", + port: [ + { + containerPort: 7878, + name: "http", + }, + ], + env: getCommonEnv(), + volumeMount: [ + { + name: "config", + mountPath: "/config", + }, + { + name: "media", + mountPath: "/media", + }, + { + name: "downloads", + mountPath: "/downloads", + }, + ], + }, + ], + volume: [ + { + name: "config", + persistentVolumeClaim: { + claimName: configPvc.name, + }, + }, + { + name: "media", + persistentVolumeClaim: { + claimName: mediaPvcName, + }, + }, + { + name: "downloads", + persistentVolumeClaim: { + claimName: downloadsPvcName, + }, + }, + ], + }, + }, + }, + }); + + // Ingress + new InternalIngressRoute(this, "ingress", { + provider, + namespace, + name, + host, + serviceName: name, + servicePort: 80, + }); + } +} diff --git a/media-services/sonarr/index.ts b/media-services/sonarr/index.ts new file mode 100644 index 0000000..eab90bf --- /dev/null +++ b/media-services/sonarr/index.ts @@ -0,0 +1,145 @@ +import { Construct } from "constructs"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; + +import { InternalIngressRoute, LonghornPvc } from "../../utils"; +import { + BaseMediaServiceOptions, + getAamil3NodeSelector, + getCommonEnv, +} from "../types"; + +type SonarrServerOptions = BaseMediaServiceOptions & { + /** Name of the shared media PVC */ + mediaPvcName: string; + /** Name of the shared downloads PVC */ + downloadsPvcName: string; + /** Hostname for the ingress */ + host: string; +}; + +export class SonarrServer extends Construct { + constructor(scope: Construct, id: string, options: SonarrServerOptions) { + super(scope, id); + + const { provider, namespace, mediaPvcName, downloadsPvcName, host } = + options; + const name = "sonarr"; + + // Config PVC with backup + const configPvc = new LonghornPvc(this, "config", { + provider, + name: "sonarr-config", + namespace, + size: "512Mi", + backup: true, + }); + + // Service + new ServiceV1(this, "service", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + app: name, + }, + port: [ + { + name: "http", + port: 80, + targetPort: "8989", + }, + ], + type: "ClusterIP", + }, + }); + + // Deployment + new DeploymentV1(this, "deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + replicas: "1", + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: getAamil3NodeSelector(), + container: [ + { + name, + image: "lscr.io/linuxserver/sonarr:latest", + imagePullPolicy: "IfNotPresent", + port: [ + { + containerPort: 8989, + name: "http", + }, + ], + env: getCommonEnv(), + volumeMount: [ + { + name: "config", + mountPath: "/config", + }, + { + name: "media", + mountPath: "/media", + }, + { + name: "downloads", + mountPath: "/downloads", + }, + ], + }, + ], + volume: [ + { + name: "config", + persistentVolumeClaim: { + claimName: configPvc.name, + }, + }, + { + name: "media", + persistentVolumeClaim: { + claimName: mediaPvcName, + }, + }, + { + name: "downloads", + persistentVolumeClaim: { + claimName: downloadsPvcName, + }, + }, + ], + }, + }, + }, + }); + + // Ingress + new InternalIngressRoute(this, "ingress", { + provider, + namespace, + name, + host, + serviceName: name, + servicePort: 80, + }); + } +} diff --git a/media-services/types.ts b/media-services/types.ts new file mode 100644 index 0000000..518efc2 --- /dev/null +++ b/media-services/types.ts @@ -0,0 +1,32 @@ +import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; + +/** + * Common options shared across all media service constructs + */ +export type BaseMediaServiceOptions = { + provider: KubernetesProvider; + namespace: string; +}; + +/** + * Common environment variables for LinuxServer.io containers + */ +export const getCommonEnv = () => [ + { name: "TZ", value: "Asia/Karachi" }, + { name: "PUID", value: "1000" }, + { name: "PGID", value: "1000" }, +]; + +/** + * Node selector for the aamil-3 node + */ +export const getAamil3NodeSelector = () => ({ + "kubernetes.io/hostname": "aamil-3", +}); + +/** + * Node selector for worker nodepool + */ +export const getWorkerNodeSelector = () => ({ + nodepool: "worker", +}); diff --git a/media/deployment.yaml b/media/deployment.yaml deleted file mode 100644 index 5dd97fd..0000000 --- a/media/deployment.yaml +++ /dev/null @@ -1,231 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: server - namespace: media -spec: - replicas: 1 - selector: - matchLabels: - app: server - template: - metadata: - labels: - app: server - spec: - nodeSelector: - kubernetes.io/hostname: aamil-3 - containers: - - name: server - image: jellyfin/jellyfin:latest - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8096 - name: http - env: - - name: TZ - value: "Asia/Karachi" - volumeMounts: - - name: config - mountPath: /config - - name: cache - mountPath: /cache - - name: media - mountPath: /media - volumes: - - name: config - persistentVolumeClaim: - claimName: jellyfin-config - - name: cache - emptyDir: {} - - name: media - persistentVolumeClaim: - claimName: media ---- -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: aamil-3 - containers: - - name: sonarr - image: lscr.io/linuxserver/sonarr:latest - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8989 - name: http - env: - - name: TZ - value: "Asia/Karachi" - - name: PUID - value: "1000" - - name: PGID - value: "1000" - volumeMounts: - - name: config - mountPath: /config - - name: media - mountPath: /media - - name: downloads - mountPath: /downloads - volumes: - - name: config - persistentVolumeClaim: - claimName: sonarr-config - - name: media - persistentVolumeClaim: - claimName: media - - name: downloads - persistentVolumeClaim: - claimName: downloads ---- -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: aamil-3 - containers: - - name: qbittorrent - image: lscr.io/linuxserver/qbittorrent:latest - ports: - - containerPort: 8080 # web UI - name: http - - containerPort: 6881 - name: bt - - containerPort: 6881 - protocol: UDP - name: bt-udp - env: - - name: TZ - value: "Asia/Karachi" - - name: PUID - value: "1000" - - name: PGID - value: "1000" - - name: WEBUI_PORT - value: "8080" - volumeMounts: - - name: config - mountPath: /config - - name: downloads - mountPath: /downloads - volumes: - - name: config - persistentVolumeClaim: - claimName: qbittorrent-config - - name: downloads - persistentVolumeClaim: - claimName: downloads ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: prowlarr - namespace: media -spec: - replicas: 1 - selector: - matchLabels: - app: prowlarr - template: - metadata: - labels: - app: prowlarr - spec: - nodeSelector: - nodepool: worker - containers: - - name: prowlarr - image: lscr.io/linuxserver/prowlarr:latest - imagePullPolicy: IfNotPresent - ports: - - containerPort: 9696 - name: http - env: - - name: TZ - value: "Asia/Karachi" - - name: PUID - value: "1000" - - name: PGID - value: "1000" - volumeMounts: - - name: config - mountPath: /config - volumes: - - name: config - persistentVolumeClaim: - claimName: prowlarr-config ---- -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: aamil-3 - containers: - - name: radarr - image: lscr.io/linuxserver/radarr:latest - imagePullPolicy: IfNotPresent - ports: - - containerPort: 7878 - name: http - env: - - name: TZ - value: "Asia/Karachi" - - name: PUID - value: "1000" - - name: PGID - value: "1000" - volumeMounts: - - name: config - mountPath: /config - - name: media - mountPath: /media - - name: downloads - mountPath: /downloads - volumes: - - name: config - persistentVolumeClaim: - claimName: radarr-config - - name: media - persistentVolumeClaim: - claimName: media - - name: downloads - persistentVolumeClaim: - claimName: downloads diff --git a/media/ingress.yaml b/media/ingress.yaml deleted file mode 100644 index 3ace2ce..0000000 --- a/media/ingress.yaml +++ /dev/null @@ -1,76 +0,0 @@ ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: server - namespace: media - annotations: - # cert-manager (Cloudflare DNS-01) - cert-manager.io/cluster-issuer: cloudflare-issuer - cert-manager.io/acme-challenge-type: dns01 - cert-manager.io/private-key-size: "4096" - - # Jellyfin / streaming friendly nginx settings - nginx.ingress.kubernetes.io/proxy-body-size: "0" - nginx.ingress.kubernetes.io/proxy-buffering: "off" - nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-http-version: "1.1" - nginx.ingress.kubernetes.io/use-proxy-protocol: "false" - nginx.ingress.kubernetes.io/proxy-request-buffering: "off" -spec: - ingressClassName: nginx-internal - tls: - - hosts: - - media.dogar.dev - secretName: media-tls - - hosts: - - sonarr.dogar.dev - secretName: sonarr-tls - - hosts: - - radarr.dogar.dev - secretName: radarr-tls - - hosts: - - torrent.dogar.dev - secretName: torrent-tls - rules: - - host: media.dogar.dev - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: server - port: - number: 80 - - host: sonarr.dogar.dev - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: sonarr - port: - number: 80 - - host: radarr.dogar.dev - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: radarr - port: - number: 80 - - host: torrent.dogar.dev - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: qbittorrent - port: - number: 80 diff --git a/media/namespace.yaml b/media/namespace.yaml deleted file mode 100644 index 6a99325..0000000 --- a/media/namespace.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: media diff --git a/media/pvc.yaml b/media/pvc.yaml deleted file mode 100644 index 456fedc..0000000 --- a/media/pvc.yaml +++ /dev/null @@ -1,106 +0,0 @@ ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: jellyfin-config - namespace: media - labels: - recurring-job.longhorn.io/source: "enabled" - recurring-job.longhorn.io/daily-backup: "enabled" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: media - namespace: media -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Ti - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: sonarr-config - namespace: media - labels: - recurring-job.longhorn.io/source: "enabled" - recurring-job.longhorn.io/daily-backup: "enabled" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 512Mi - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: qbittorrent-config - namespace: media - labels: - recurring-job.longhorn.io/source: "enabled" - recurring-job.longhorn.io/daily-backup: "enabled" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 512Mi - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: downloads - namespace: media -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 450Gi - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: prowlarr-config - namespace: media - labels: - recurring-job.longhorn.io/source: "enabled" - recurring-job.longhorn.io/daily-backup: "enabled" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 512Mi - storageClassName: longhorn ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: radarr-config - namespace: media - labels: - recurring-job.longhorn.io/source: "enabled" - recurring-job.longhorn.io/daily-backup: "enabled" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 512Mi - storageClassName: longhorn diff --git a/media/service.yaml b/media/service.yaml deleted file mode 100644 index 1bae7a8..0000000 --- a/media/service.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: server - namespace: media -spec: - selector: - app: server - ports: - - name: http - port: 80 - targetPort: 8096 - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - name: sonarr - namespace: media -spec: - selector: - app: sonarr - ports: - - name: http - port: 80 - targetPort: 8989 - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - name: qbittorrent - namespace: media -spec: - selector: - app: qbittorrent - ports: - - name: http - port: 80 - targetPort: 8080 - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - name: prowlarr - namespace: media -spec: - selector: - app: prowlarr - ports: - - name: http - port: 80 - targetPort: 9696 - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - name: radarr - namespace: media -spec: - selector: - app: radarr - ports: - - name: http - port: 80 - targetPort: 7878