diff --git a/apps/plex/base/deployment.yaml b/apps/plex/base/deployment.yaml new file mode 100644 index 0000000..ebeda7e --- /dev/null +++ b/apps/plex/base/deployment.yaml @@ -0,0 +1,73 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: plex + labels: + app: plex +spec: + replicas: 1 + selector: + matchLabels: + app: plex + template: + metadata: + annotations: + labels: + app: plex + spec: + volumes: + - name: plex-config + persistentVolumeClaim: + claimName: plex-config + containers: + - name: plex + image: plexinc/pms-docker:plexpass + imagePullPolicy: Always + resources: + requests: + cpu: 1 + memory: 512Mi + ports: + - containerPort: 32400 + name: http + - containerPort: 32400 + name: plex-udp + protocol: UDP + - containerPort: 32469 + name: plex-dlna + - containerPort: 1900 + name: plex-dlna-udp + protocol: UDP + - containerPort: 5353 + name: plex-discovery + protocol: UDP + - containerPort: 3005 + name: plex-comp + - containerPort: 32410 + name: plex-gdm1 + protocol: UDP + - containerPort: 32412 + name: plex-gdm2 + protocol: UDP + - containerPort: 32413 + name: plex-gdm3 + protocol: UDP + - containerPort: 32414 + name: plex-gdm4 + protocol: UDP + env: + - name: GID + value: "1000" + - name: UID + value: "1000" + - name: PLEX_GID + value: "1000" + - name: PLEX_UID + value: "1000" + - name: CHANGE_CONFIG_DIR_OWNERSHIP + value: "false" + - name: TZ + value: UTC + volumeMounts: + - mountPath: /config + name: plex-config diff --git a/apps/plex/base/graphana.yaml b/apps/plex/base/graphana.yaml new file mode 100644 index 0000000..e992416 --- /dev/null +++ b/apps/plex/base/graphana.yaml @@ -0,0 +1,545 @@ +# NOTE: this is not tested and not currently included in kustomization.yaml + +apiVersion: v1 +kind: ConfigMap +metadata: + name: plex-grafana + namespace: grafana #Needs to match the Grafana installation namespace + labels: + grafana-dashboard: "1" #Required to have the Grafana sidecar container pick up the new dashboard +data: + plex-prometheus.json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 3, + "links": [], + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum(plex_library_section_size_count)", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Library items", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 0 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum(plex_sessions_active_count)", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Active sessions", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 0 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum(plex_transcode_sessions_active_count)", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Transcode sessions", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltipOptions": { + "mode": "single" + } + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum (plex_library_section_size_count) by (name)", + "interval": "", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Library items by Name", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltipOptions": { + "mode": "single" + } + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum (plex_sessions_active_count)", + "interval": "", + "legendFormat": "Sessions", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Active sessions", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltipOptions": { + "mode": "single" + } + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"plex.*\",pod!~\"plex-exporter.*\"}[1m]))by(pod)", + "interval": "", + "legendFormat": "{{container}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Pod CPU usage", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltipOptions": { + "mode": "single" + } + }, + "pluginVersion": "7.5.6", + "targets": [ + { + "exemplar": true, + "expr": "sum (container_memory_working_set_bytes{pod=~\"plex.*\",pod!~\"plex-exporter.*\"}) by (container_name, pod_name)", + "interval": "", + "legendFormat": "Memory", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Pod Memory usage", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Plex", + "uid": "w8ttuLbnk", + "version": 10 + } diff --git a/apps/plex/base/kustomization.yaml b/apps/plex/base/kustomization.yaml new file mode 100644 index 0000000..8c86dce --- /dev/null +++ b/apps/plex/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - deployment.yaml + - pvc.yaml + - service.yaml +# - graphana.yaml +# - prometheus-exporter.yaml diff --git a/apps/plex/base/prometheus-exporter.yaml b/apps/plex/base/prometheus-exporter.yaml new file mode 100644 index 0000000..b05ba91 --- /dev/null +++ b/apps/plex/base/prometheus-exporter.yaml @@ -0,0 +1,68 @@ +# NOTE: this is not tested and not currently included in kustomization.yaml + +apiVersion: v1 +kind: ConfigMap +metadata: + name: plex-exporter +data: + config.yaml: | + address: ":9594" + logLevel: "info" + logFormat: "text" + autoDiscover: false + token: "" + servers: + - baseUrl: http://plex-tcp +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: plex-exporter + namespace: plex + labels: + app: plex-exporter +spec: + replicas: 1 + selector: + matchLabels: + app: plex-exporter + template: + metadata: + labels: + app: plex-exporter + annotations: + prometheus.io/scrape: "true" + prometheus.io/scheme: "http" + prometheus.io/path: "/metrics" + prometheus.io/port: "9594" + spec: + containers: + - name: plex-exporter + image: granra/plex_exporter:v0.2.3 + imagePullPolicy: Always + ports: + - containerPort: 9594 + name: metrics + volumeMounts: + - name: config + mountPath: /etc/plex_exporter/config.yaml + subPath: config.yaml + volumes: + - name: config + configMap: + name: plex-exporter +--- +kind: Service +apiVersion: v1 +metadata: + name: plex-exporter + namespace: plex +spec: + selector: + app: plex-exporter + ports: + - port: 9594 + name: metrics + protocol: TCP + type: ClusterIP #Change to LoadBalancer if you want to check out the metrics page directly + diff --git a/apps/plex/base/pvc.yaml b/apps/plex/base/pvc.yaml new file mode 100644 index 0000000..8925c78 --- /dev/null +++ b/apps/plex/base/pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-config +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi diff --git a/apps/plex/base/service.yaml b/apps/plex/base/service.yaml new file mode 100644 index 0000000..0ad21c7 --- /dev/null +++ b/apps/plex/base/service.yaml @@ -0,0 +1,38 @@ +kind: Service +apiVersion: v1 +metadata: + name: plex-udp + # annotations: + # metallb.universe.tf/allow-shared-ip: plexserver # annotation name to combine the Service IP, make sure it's same name as in the service UDP yaml +spec: + selector: + app: plexserver + ports: + - port: 1900 + targetPort: plex-dlna-udp + name: dlna-udp + protocol: UDP + - port: 5353 + targetPort: plex-discovery + name: discovery-udp + protocol: UDP + +--- +kind: Service +apiVersion: v1 +metadata: + name: plex-tcp + # annotations: + # metallb.universe.tf/allow-shared-ip: plexserver +spec: + selector: + app: plexserver + ports: + - port: 80 + targetPort: http + name: http + protocol: TCP + - port: 32469 + targetPort: plex-dlna + name: dlna-tcp + protocol: TCP diff --git a/apps/plex/overlays/media/audiobooks-pvc.yaml b/apps/plex/overlays/media/audiobooks-pvc.yaml new file mode 100644 index 0000000..0c26949 --- /dev/null +++ b/apps/plex/overlays/media/audiobooks-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-data-audiobooks +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 20Gi diff --git a/apps/plex/overlays/media/cert.sops.pem b/apps/plex/overlays/media/cert.sops.pem new file mode 100644 index 0000000..d6a1e9f --- /dev/null +++ b/apps/plex/overlays/media/cert.sops.pem @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:uVfizKnFIFJStCPtdNEJBe4apghX/DbJim4kM75KtuL/TQJ/WJ8Cas5o2Q1cwMggkpuSLCyo6BUwWQoYjSvTonVkFU26O8n2m1Y62Lukg7fOY2ZYvzj79c+YlWPDGstdh1CtGMPdgmZfmC/YlJDyXxx/it4jiCvK2ADF4s+HECfwgOyN5YMwrliPgj3J3maVQAMjnDcs540k1uh3l8bWA+keLE9bqSIEZSQ/e/RkaZ02JDYssFEhCTWBY9RYzaQ5DvXvN8UjdeCz5EtfSeZICxitvkYPjEfLZ9CNAhVnnGTM8/6p1xWNiEnnSwrNqpJ+zK3cixkQNlTgcDA8tcOtTzqU8POtj5itOrJV0mCwpyArK2DfungDR4P0nVlBBuqPxiWjufpDxUfg+IPFhxFKHHGZaOvDZfiXwT/mZFwp31wUbdaKLQkqWAHcAyUN/pabjWzOhSdCWEFh/VlPX4a1CW/yl8YYPEqGz4gzJ9SUM29cUH4GoyLksC/bFf5J92sZ50dj5QD12duuVqYmJGLqTphSjsnRv7AO4EdpFSvO69WoxzkcGzx92dK5mw4RcuW5SCEfu4XaZWCVLCBpnp9Rl3R6BPUdckh5nbDp6L99++swgReZ4z4wWgeUZ60yTgcO+wH5FBGIWBTNlA8Z+C/d3ZGboU4zGqIr6X3ohDu/jKjgA0+2OBcEXPm/zHp2QfqQmUk48AlDUnxcX7wGEB4l48ErBNjhyreNWkmuoZtLwdQUeQc+vstnLOdx3sbMEUVEvyvZVzTfLMhJvkCfFjZyIF7fynNtvMn8wnUSumPkGQ5FqVh1uNnX,iv:zsUQSb6qkBpr5TLYy0FCV4X6b4exTYxmlp+q5wCZoCw=,tag:EIPkQItZvaLUkm9HoQdILw==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1y26vr5qt6th3wu92rnsgkqcpxxah3pqkqa4khcjjycm3kg40aqyqjgfzx9", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByYnVhODBJV091cXFTbk13\nWUhWREgvMTlGSUtxRUptazA3OUlONjZMV0g0CmhwTFJiZk1zZjA2a2RncHNmdmZX\nckRyNVpPWVJsTlp5ZDlaWWhHcG5TQzgKLS0tIC9EUEFJOFlBWVBVc285RzdYVXlq\nc0RBRW5SNy9wL2s2Q0Fpa21JREVwVlkKIHnlUKipzptrJUyzQumGiSRVm+hsEuq8\n+o7772jG0rwsLt0xQ3cKaQP2Rfeiul3QQXde7bEuT8T/iN6fBZPYkg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2024-05-25T13:09:08Z", + "mac": "ENC[AES256_GCM,data:c84fztj6EhtZtm9IdIy3qEq0EFjl4Id5IG1B8kaZChnScTNFLTKb8Hlbc6GMVFM11FfOjscfe6/oa1eZAk6bM4V0LNFi5ysXIbByPcUy5ZaA1agUtSKOlQOD0lIaONhzaAVuQWD7W7m7vz1nYVoUEBNvFplkoZqVgllenJiq4Jo=,iv:CeOKU8Vfls5Bc//n/uTKNJlz6ZwtNskPVj7Da3otw0U=,tag:wkh25T/s1p+oRRuAlYQdZw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.8.1" + } +} diff --git a/apps/plex/overlays/media/claim-token.sops b/apps/plex/overlays/media/claim-token.sops new file mode 100644 index 0000000..e222396 --- /dev/null +++ b/apps/plex/overlays/media/claim-token.sops @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:1ng8X1bX139ZqGl+eDddCW13jA6y,iv:/ND91I5kHCbywZKI790D65k9bAPLnuVVH8PQUrTsscM=,tag:Q/dxzOYuegd+W+5MXMeLHA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1y26vr5qt6th3wu92rnsgkqcpxxah3pqkqa4khcjjycm3kg40aqyqjgfzx9", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwd3BYZjJkZ3hBaU4weEQ3\nWEhOYVk1Snl5NXg4ZGlVT0lQYTJzck9IYjNzCnQzOVNTenA4T1J0dldiNFMwMmkz\neG1TWndYcVRiaHFublYwdHFpdzE1K0EKLS0tIHppVXI3T24wdzZDNXdqUFBvZURv\nMG5oSVZVYWVTTXQ2VEE1RGpwK2tDN3cKgGRUwjU4xm+hlWuPFKlsZ0d45bsf17lE\naf7VXqgYCHNPiAODVYUobVNuMYuJya132Cmu8kB6Ku+L1odgQ7Fofw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2024-05-27T20:05:44Z", + "mac": "ENC[AES256_GCM,data:Aq6ijTj9RL11hpnEhr8/MJeLa37s662FUAVVPdF7pOOs120X9yINNLIPtThd2qI0A7N56HwFHjAt5N9yLYkMc/vzDgtTJXCDPmS0/OPmy+RRN6uWiUq6Rct21l1oHwZ6Ce3bnkwQhuXb13m6rlUZfAjLG1DYJWFKPsayyM6FPMk=,iv:MpkMTuWvolQlZAZX+ettEVMQw08kmOa+uqSl6gOsL9M=,tag:aFw56/V3ltBO3nF5FKUFUw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.8.1" + } +} diff --git a/apps/plex/overlays/media/config.json b/apps/plex/overlays/media/config.json new file mode 100644 index 0000000..0add7cd --- /dev/null +++ b/apps/plex/overlays/media/config.json @@ -0,0 +1,11 @@ +{ + "appName": "plex", + "userGivenName": "plex", + "destNamespace": "media", + "destServer": "https://kubernetes.default.svc", + "srcPath": "apps/plex/overlays/media", + "srcRepoURL": "ssh://git@gitea-ssh.gitops.svc.cluster.local:2222/davad/argo.git", + "srcTargetRevision": "", + "labels": null, + "annotations": null +} diff --git a/apps/plex/overlays/media/deployment-patch.yaml b/apps/plex/overlays/media/deployment-patch.yaml new file mode 100644 index 0000000..69c0541 --- /dev/null +++ b/apps/plex/overlays/media/deployment-patch.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: plex +spec: + template: + spec: + volumes: + - name: plex-data-audiobooks + nfs: + server: 192.168.1.215 + path: /export/audiobooks + - name: plex-data-music + nfs: + server: 192.168.1.215 + path: /export/music + - name: plex-data-videos + nfs: + server: 192.168.1.215 + path: /export/videos + containers: + - name: plex + env: + - name: PLEX_CLAIM + valueFrom: + secretKeyRef: + name: plex-claim + key: claim-token + + - name: ADVERTISE_IP + value: https://plex.nc.landry.land + - name: HOSTNAME + value: plex.nc.landry.land + - name: ALLOWED_NETWORKS + value: 192.168.1.1/16 + volumeMounts: + - mountPath: /audiobooks + name: plex-data-audiobooks + - mountPath: /music + name: plex-data-music + - mountPath: /media + name: plex-data-videos diff --git a/apps/plex/overlays/media/ingress.yaml b/apps/plex/overlays/media/ingress.yaml new file mode 100644 index 0000000..38ee33a --- /dev/null +++ b/apps/plex/overlays/media/ingress.yaml @@ -0,0 +1,30 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: plex + labels: + app.kubernetes.io/name: plex + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + + gethomepage.dev/enabled: "true" + gethomepage.dev/name: plex + gethomepage.dev/group: Files + gethomepage.dev/href: https://plex.nc.landry.land + gethomepage.dev/description: Movies, Music, TV shows, and Audiobooks + gethomepage.dev/icon: plex +spec: + tls: + - hosts: + - "plex.nc.landry.land" + rules: + - host: "plex.nc.landry.land" + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: plex-tcp + port: + name: http diff --git a/apps/plex/overlays/media/kustomization.yaml b/apps/plex/overlays/media/kustomization.yaml new file mode 100644 index 0000000..c51fcfb --- /dev/null +++ b/apps/plex/overlays/media/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ../../base + - ingress.yaml + - audiobooks-pvc.yaml + - music-pvc.yaml + - photos-pvc.yaml + - videos-pvc.yaml + +patches: + - path: deployment-patch.yaml + +generators: + - secrets.yaml diff --git a/apps/plex/overlays/media/music-pvc.yaml b/apps/plex/overlays/media/music-pvc.yaml new file mode 100644 index 0000000..af9c9e2 --- /dev/null +++ b/apps/plex/overlays/media/music-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-data-music +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 20Gi diff --git a/apps/plex/overlays/media/photos-pvc.yaml b/apps/plex/overlays/media/photos-pvc.yaml new file mode 100644 index 0000000..5464a5f --- /dev/null +++ b/apps/plex/overlays/media/photos-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-data-photos +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 20Gi diff --git a/apps/plex/overlays/media/secrets.yaml b/apps/plex/overlays/media/secrets.yaml new file mode 100644 index 0000000..f5377eb --- /dev/null +++ b/apps/plex/overlays/media/secrets.yaml @@ -0,0 +1,14 @@ +apiVersion: viaduct.ai/v1 +kind: ksops +metadata: + name: ksops-generator + annotations: + config.kubernetes.io/function: | + exec: + path: ksops +secretFrom: + - metadata: + name: plex-claim + type: Opaque + binaryFiles: + - claim-token=./claim-token.sops diff --git a/apps/plex/overlays/media/videos-pvc.yaml b/apps/plex/overlays/media/videos-pvc.yaml new file mode 100644 index 0000000..4e59801 --- /dev/null +++ b/apps/plex/overlays/media/videos-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-data-videos +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 20Gi