mirror of
https://github.com/morten-olsen/homelab-apps.git
synced 2026-02-08 01:36:28 +01:00
add tubearchivist
This commit is contained in:
@@ -37,6 +37,9 @@ volumes:
|
||||
- name: kidsmusic
|
||||
mountPath: /media/kids-music
|
||||
persistentVolumeClaim: kidsmusic # External PVC (not prefixed)
|
||||
- name: media
|
||||
mountPath: /media/youtube
|
||||
persistentVolumeClaim: kidsyoutube # External PVC (not prefixed with release name)
|
||||
|
||||
# Persistent volume claims
|
||||
persistentVolumeClaims:
|
||||
|
||||
7
apps/charts/tubearchivist/Chart.yaml
Normal file
7
apps/charts/tubearchivist/Chart.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v2
|
||||
version: 1.0.0
|
||||
name: tubearchivist
|
||||
dependencies:
|
||||
- name: common
|
||||
version: 1.0.0
|
||||
repository: file://../../common
|
||||
1
apps/charts/tubearchivist/templates/deployment.yaml
Normal file
1
apps/charts/tubearchivist/templates/deployment.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{{ include "common.deployment" . }}
|
||||
@@ -0,0 +1,87 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-es"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
app: "{{ .Release.Name }}-es"
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: "{{ .Release.Name }}-es"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: "{{ .Release.Name }}-es"
|
||||
spec:
|
||||
initContainers:
|
||||
- name: fix-permissions
|
||||
image: busybox:latest
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
mkdir -p /usr/share/elasticsearch/data
|
||||
chown -R 1000:1000 /usr/share/elasticsearch/data
|
||||
chmod -R 755 /usr/share/elasticsearch/data
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/share/elasticsearch/data
|
||||
containers:
|
||||
- name: "{{ .Release.Name }}-es"
|
||||
image: "{{ .Values.elasticsearch.image.repository }}:{{ .Values.elasticsearch.image.tag }}"
|
||||
imagePullPolicy: "{{ .Values.elasticsearch.image.pullPolicy }}"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 9200
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: ELASTIC_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Release.Name }}-secrets"
|
||||
key: elastic-password
|
||||
- name: ES_JAVA_OPTS
|
||||
value: "-Xms1g -Xmx1g"
|
||||
- name: xpack.security.enabled
|
||||
value: "true"
|
||||
- name: discovery.type
|
||||
value: "single-node"
|
||||
- name: path.repo
|
||||
value: "/usr/share/elasticsearch/data/snapshot"
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/share/elasticsearch/data
|
||||
resources:
|
||||
limits:
|
||||
memory: "2Gi"
|
||||
requests:
|
||||
memory: "1Gi"
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
curl -s -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cluster/health | grep -q '"status":"green"\|"status":"yellow"'
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: "{{ .Release.Name }}-es-data"
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-es"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
app: "{{ .Release.Name }}-es"
|
||||
spec:
|
||||
ports:
|
||||
- port: 9200
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: "{{ .Release.Name }}-es"
|
||||
27
apps/charts/tubearchivist/templates/pvc.yaml
Normal file
27
apps/charts/tubearchivist/templates/pvc.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
{{ include "common.pvc" . }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-redis-data"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-es-data"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
63
apps/charts/tubearchivist/templates/redis-deployment.yaml
Normal file
63
apps/charts/tubearchivist/templates/redis-deployment.yaml
Normal file
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-redis"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
app: "{{ .Release.Name }}-redis"
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: "{{ .Release.Name }}-redis"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: "{{ .Release.Name }}-redis"
|
||||
spec:
|
||||
initContainers:
|
||||
- name: fix-permissions
|
||||
image: busybox:latest
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
mkdir -p /data
|
||||
chown -R 999:999 /data || chown -R 0:0 /data
|
||||
chmod -R 755 /data
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
containers:
|
||||
- name: "{{ .Release.Name }}-redis"
|
||||
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
|
||||
imagePullPolicy: "{{ .Values.redis.image.pullPolicy }}"
|
||||
ports:
|
||||
- name: tcp
|
||||
containerPort: 6379
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
command:
|
||||
- redis-server
|
||||
- --appendonly
|
||||
- "no"
|
||||
- --save
|
||||
- ""
|
||||
- --stop-writes-on-bgsave-error
|
||||
- "no"
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: tcp
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: tcp
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: "{{ .Release.Name }}-redis-data"
|
||||
15
apps/charts/tubearchivist/templates/redis-service.yaml
Normal file
15
apps/charts/tubearchivist/templates/redis-service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-redis"
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
app: "{{ .Release.Name }}-redis"
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: tcp
|
||||
protocol: TCP
|
||||
name: tcp
|
||||
selector:
|
||||
app: "{{ .Release.Name }}-redis"
|
||||
@@ -0,0 +1 @@
|
||||
{{ include "common.externalSecrets.externalSecrets" . }}
|
||||
@@ -0,0 +1 @@
|
||||
{{ include "common.externalSecrets.passwordGenerators" . }}
|
||||
1
apps/charts/tubearchivist/templates/service.yaml
Normal file
1
apps/charts/tubearchivist/templates/service.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{{ include "common.service" . }}
|
||||
1
apps/charts/tubearchivist/templates/virtual-service.yaml
Normal file
1
apps/charts/tubearchivist/templates/virtual-service.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{{ include "common.virtualService" . }}
|
||||
116
apps/charts/tubearchivist/values.yaml
Normal file
116
apps/charts/tubearchivist/values.yaml
Normal file
@@ -0,0 +1,116 @@
|
||||
image:
|
||||
repository: bbilly1/tubearchivist
|
||||
tag: latest
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
subdomain: tubearchivist
|
||||
|
||||
# Use the image's default CMD as specified in Dockerfile
|
||||
# Dependencies are already installed in /root/.local from the multi-stage build
|
||||
# Note: tini location may vary, using bash directly as fallback
|
||||
command:
|
||||
- /bin/bash
|
||||
- /app/run.sh
|
||||
|
||||
# Deployment configuration
|
||||
deployment:
|
||||
strategy: Recreate
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
podAnnotations:
|
||||
sidecar.istio.io/rewriteAppHTTPProbers: "false"
|
||||
|
||||
# Container configuration
|
||||
container:
|
||||
ports:
|
||||
- name: http
|
||||
port: 8000
|
||||
protocol: TCP
|
||||
healthProbe:
|
||||
type: tcpSocket
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 120
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 3
|
||||
# securityContext removed - image expects to run as root to access /root/.local packages
|
||||
|
||||
# Service configuration
|
||||
service:
|
||||
port: 80
|
||||
targetPort: http
|
||||
type: ClusterIP
|
||||
|
||||
# Volume configuration
|
||||
volumes:
|
||||
- name: media
|
||||
mountPath: /youtube
|
||||
persistentVolumeClaim: kidsyoutube # External PVC (not prefixed with release name)
|
||||
- name: cache
|
||||
mountPath: /cache
|
||||
persistentVolumeClaim: data # Use "data" so common library prefixes it correctly
|
||||
|
||||
# Persistent volume claims
|
||||
persistentVolumeClaims:
|
||||
- name: data
|
||||
size: 10Gi
|
||||
|
||||
# VirtualService configuration
|
||||
virtualService:
|
||||
enabled: true
|
||||
gateways:
|
||||
public: true
|
||||
private: true
|
||||
|
||||
# External Secrets configuration for initial credentials
|
||||
externalSecrets:
|
||||
- name: "{release}-secrets"
|
||||
passwords:
|
||||
- name: ta-password
|
||||
length: 32
|
||||
allowRepeat: true
|
||||
encoding: hex
|
||||
secretKeys:
|
||||
- ta-password
|
||||
- name: elastic-password
|
||||
length: 32
|
||||
allowRepeat: true
|
||||
encoding: hex
|
||||
secretKeys:
|
||||
- elastic-password
|
||||
|
||||
# Environment variables
|
||||
env:
|
||||
ES_URL:
|
||||
value: "http://{release}-es.{namespace}.svc.cluster.local:9200"
|
||||
REDIS_CON:
|
||||
value: "redis://{release}-redis.{namespace}.svc.cluster.local:6379"
|
||||
HOST_UID: "1000"
|
||||
HOST_GID: "1000"
|
||||
TA_HOST:
|
||||
value: "https://{subdomain}.{domain}"
|
||||
TA_USERNAME: "tubearchivist"
|
||||
TA_PASSWORD:
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{release}-secrets"
|
||||
key: ta-password
|
||||
ELASTIC_PASSWORD:
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{release}-secrets"
|
||||
key: elastic-password
|
||||
|
||||
# Redis configuration
|
||||
redis:
|
||||
image:
|
||||
repository: redis
|
||||
tag: latest
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Elasticsearch configuration
|
||||
elasticsearch:
|
||||
image:
|
||||
repository: bbilly1/tubearchivist-es
|
||||
tag: latest
|
||||
pullPolicy: IfNotPresent
|
||||
@@ -20,5 +20,5 @@ shares:
|
||||
path: /mnt/HDD/Misc
|
||||
kidsmusic:
|
||||
path: /mnt/HDD/Misc/Kids_Music
|
||||
images:
|
||||
path: /mnt/HDD/images
|
||||
kidsyoutube:
|
||||
path: /mnt/HDD/Kids/YouTube
|
||||
|
||||
@@ -185,12 +185,16 @@ externalSecrets:
|
||||
passwords:
|
||||
- name: apiKey
|
||||
length: 32
|
||||
encoding: hex # or base64, alphanumeric
|
||||
encoding: hex # Supported: base64, base64url, base32, hex, raw
|
||||
allowRepeat: true
|
||||
secretKeys: # Required: sets the key name in the secret
|
||||
- apiKey
|
||||
- name: encryptionKey
|
||||
length: 64
|
||||
encoding: base64
|
||||
allowRepeat: false
|
||||
secretKeys: # Required: sets the key name in the secret
|
||||
- encryptionKey
|
||||
|
||||
# Environment variables
|
||||
env:
|
||||
@@ -271,6 +275,8 @@ Add secret generation templates:
|
||||
{{ include "common.externalSecrets.externalSecrets" . }}
|
||||
```
|
||||
|
||||
**Note:** Remember to include `secretKeys` in each password configuration in `values.yaml` to set the key names in the generated secret. See the [External Secrets](#external-secrets) section for details.
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Example 1: Simple Stateless Application
|
||||
@@ -429,10 +435,14 @@ externalSecrets:
|
||||
length: 64
|
||||
encoding: base64
|
||||
allowRepeat: true
|
||||
secretKeys: # Required: sets the key name in the secret
|
||||
- encryptionKey
|
||||
- name: apiToken
|
||||
length: 32
|
||||
encoding: hex
|
||||
allowRepeat: false
|
||||
secretKeys: # Required: sets the key name in the secret
|
||||
- apiToken
|
||||
|
||||
env:
|
||||
ENCRYPTION_KEY:
|
||||
@@ -489,7 +499,26 @@ When `database.enabled: true`, the PostgresDatabase creates a secret named `{rel
|
||||
|
||||
### External Secrets
|
||||
|
||||
External secrets are created with the name specified in `externalSecrets[].name` (use `{release}` placeholder). Each password field becomes a key in the secret.
|
||||
External secrets are created with the name specified in `externalSecrets[].name` (use `{release}` placeholder).
|
||||
|
||||
**Important:** The `secretKeys` field is **required** for each password generator to set the key name in the secret. Without `secretKeys`, the Password generator defaults to using `password` as the key name. The `name` field in the password config is used for the generator name, not the secret key name.
|
||||
|
||||
**Supported encodings:** `base64`, `base64url`, `base32`, `hex`, `raw` (note: `alphanumeric` is not supported)
|
||||
|
||||
**Example:**
|
||||
```yaml
|
||||
externalSecrets:
|
||||
- name: "{release}-secrets"
|
||||
passwords:
|
||||
- name: my-password-generator # Generator name (used in resource name)
|
||||
length: 32
|
||||
encoding: hex
|
||||
allowRepeat: true
|
||||
secretKeys: # Required: sets the key name in the secret
|
||||
- mySecretKey # This becomes the key name in the secret
|
||||
```
|
||||
|
||||
The secret will contain a key named `mySecretKey` (not `my-password-generator`).
|
||||
|
||||
## Placeholders
|
||||
|
||||
|
||||
@@ -330,6 +330,10 @@ spec:
|
||||
{{- include "common.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- if .Values.deployment.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.deployment.podAnnotations | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "common.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
|
||||
Reference in New Issue
Block a user