diff --git a/k3s/apps/Nextcloud/README.md b/k3s/apps/Nextcloud/README.md new file mode 100644 index 0000000..b216744 --- /dev/null +++ b/k3s/apps/Nextcloud/README.md @@ -0,0 +1,2 @@ +smb user nextcloud +smb pass qCPJgc7C \ No newline at end of file diff --git a/k3s/apps/Nextcloud/helm/cleanRestart.sh b/k3s/apps/Nextcloud/helm/cleanRestart.sh new file mode 100755 index 0000000..019a7ad --- /dev/null +++ b/k3s/apps/Nextcloud/helm/cleanRestart.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Konfiguration (anpassen falls nötig) +NAMESPACE="nextcloud" +RELEASE="nextcloud" +CHART="nextcloud/nextcloud" +VALUES_FILE="values-nextcloud.yaml" +SMB_SCRIPT_FILE="install-smb.sh" +CONFIGMAP_NAME="smb-install-script" +HELM_REPO_NAME="nextcloud" +HELM_REPO_URL="https://nextcloud.github.io/helm/" +WAIT_TIMEOUT="600s" # Timeout für Pod-Readiness (10m) + +# Hilfsfunktionen +err() { echo "ERROR: $*" >&2; exit 1; } +info() { echo "INFO: $*"; } + +confirm() { + echo + echo "!!! Achtung: Das Skript wird das Helm-Release '$RELEASE' im Namespace '$NAMESPACE' deinstallieren" + echo " und alle zugehörigen PersistentVolumeClaims (PVCs) löschen. Daten gehen verloren!" + echo + read -p "Tippe DELETE um fortzufahren (oder STRG-C zum Abbrechen): " ans + if [ "$ans" != "DELETE" ]; then + echo "Abgebrochen." + exit 0 + fi +} + +check_tools() { + command -v kubectl >/dev/null 2>&1 || err "kubectl ist nicht installiert oder nicht in PATH" + command -v helm >/dev/null 2>&1 || err "helm ist nicht installiert oder nicht in PATH" +} + +create_namespace_if_missing() { + if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then + info "Namespace $NAMESPACE existiert nicht — wird angelegt" + kubectl create namespace "$NAMESPACE" + else + info "Namespace $NAMESPACE existiert" + fi +} + +uninstall_release() { + if helm -n "$NAMESPACE" status "$RELEASE" >/dev/null 2>&1; then + info "Helm-Release '$RELEASE' gefunden -> deinstalliere..." + helm -n "$NAMESPACE" uninstall "$RELEASE" + info "Warte bis alle Pods des Releases entfernt sind..." + # Warte bis keine Pods mehr mit dem Release-Label vorhanden sind + for i in $(seq 1 60); do + sleep 2 + COUNT=$(kubectl -n "$NAMESPACE" get pods -l app.kubernetes.io/instance="$RELEASE" --no-headers 2>/dev/null | wc -l || true) + if [ "$COUNT" -eq 0 ]; then + break + fi + echo -n "." + done + echo + else + info "Kein bestehendes Helm-Release '$RELEASE' gefunden" + fi +} + +delete_pvcs() { + # Liste PVCs, die zum Release gehören (Label app.kubernetes.io/instance) + PVCS=$(kubectl -n "$NAMESPACE" get pvc -l app.kubernetes.io/instance="$RELEASE" -o jsonpath='{.items[*].metadata.name}' || true) + if [ -z "$PVCS" ]; then + info "Keine PVCs mit Label app.kubernetes.io/instance=$RELEASE gefunden" + return + fi + + info "Folgende PVCs werden gelöscht: $PVCS" + kubectl -n "$NAMESPACE" delete pvc $PVCS + info "Warte auf Löschung der PVCs..." + for pvc in $PVCS; do + kubectl -n "$NAMESPACE" wait --for=delete pvc/"$pvc" --timeout=120s || true + done +} + +recreate_configmap() { + if [ ! -f "$SMB_SCRIPT_FILE" ]; then + err "SMB-Script '$SMB_SCRIPT_FILE' fehlt. Lege die Datei an oder passe \$SMB_SCRIPT_FILE an." + fi + info "Erstelle/aktualisiere ConfigMap $CONFIGMAP_NAME aus $SMB_SCRIPT_FILE" + kubectl -n "$NAMESPACE" create configmap "$CONFIGMAP_NAME" --from-file="$SMB_SCRIPT_FILE" -o yaml --dry-run=client | kubectl apply -f - +} + +add_helm_repo() { + # Add repo if not exists + if ! helm repo list | awk '{print $1}' | grep -xq "$HELM_REPO_NAME"; then + info "Füge Helm-Repo $HELM_REPO_NAME hinzu" + helm repo add "$HELM_REPO_NAME" "$HELM_REPO_URL" + fi + helm repo update +} + +install_release() { + if [ ! -f "$VALUES_FILE" ]; then + err "Values-File '$VALUES_FILE' nicht gefunden. Abbruch." + fi + info "Installiere Helm-Release '$RELEASE' mit values '$VALUES_FILE'" + helm upgrade --install "$RELEASE" "$CHART" -n "$NAMESPACE" -f "$VALUES_FILE" +} + +wait_pods_ready() { + info "Warte bis alle Pods des Releases ready sind (Timeout $WAIT_TIMEOUT)..." + # Warte auf Ready-Bedingung für alle Pods mit dem instance-Label + if ! kubectl -n "$NAMESPACE" wait --for=condition=Ready pod -l app.kubernetes.io/instance="$RELEASE" --all --timeout="$WAIT_TIMEOUT"; then + echo "WARNUNG: Nicht alle Pods sind innerhalb des Timeouts ready. Aktuelle Pods:" + kubectl -n "$NAMESPACE" get pods -o wide + return 1 + fi + info "Alle Pods sind ready." +} + +post_checks() { + info "Prüfe smbclient im Nextcloud-Container (falls Pod läuft)..." + POD=$(kubectl -n "$NAMESPACE" get pod -l app.kubernetes.io/instance="$RELEASE",app.kubernetes.io/component=app -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true) + if [ -n "$POD" ]; then + kubectl -n "$NAMESPACE" exec -it "$POD" -- sh -c 'command -v smbclient && smbclient -V || echo "smbclient nicht gefunden"' + else + info "Nextcloud-App-Pod nicht gefunden (noch nicht gestartet)." + fi + info "Führe 'occ files_external:backends' aus (falls Pod läuft)..." + if [ -n "$POD" ]; then + kubectl -n "$NAMESPACE" exec -it "$POD" -- sh -c 'php /var/www/html/occ files_external:backends || true' + fi +} + +main() { + check_tools + confirm + create_namespace_if_missing + + uninstall_release + delete_pvcs + +# recreate_configmap +# add_helm_repo +# install_release + +# # Warte auf Pods +# if ! wait_pods_ready; then +# info "Einige Pods sind möglicherweise nicht ready. Schaue in die Logs:" +# kubectl -n "$NAMESPACE" get pods +# kubectl -n "$NAMESPACE" logs -l app.kubernetes.io/instance="$RELEASE" --tail=100 || true +# fi + +# post_checks + + echo + echo "Fertig. Prüfe die Nextcloud-WebUI und gegebenenfalls die External Storage Einstellungen." +} + +main "$@" \ No newline at end of file diff --git a/k3s/apps/Nextcloud/helm/install-smb.sh b/k3s/apps/Nextcloud/helm/install-smb.sh new file mode 100644 index 0000000..faece49 --- /dev/null +++ b/k3s/apps/Nextcloud/helm/install-smb.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -eux + +# Installiere SMB Tools in einem Init-Container und kopiere sie in ein shared Volume, +# damit der Nextcloud-Container smbclient nutzen kann. +apt-get update +apt-get install -y --no-install-recommends smbclient libsmbclient-dev libwbclient0 ca-certificates + +mkdir -p /opt/smb-tools/bin /opt/smb-tools/lib + +# Binary +cp -a /usr/bin/smbclient /opt/smb-tools/bin/ + +# Libraries (best effort; Pfade können je nach Debian-Release leicht variieren) +cp -a /usr/lib/x86_64-linux-gnu/libsmbclient.so* /opt/smb-tools/lib/ || true +cp -a /usr/lib/x86_64-linux-gnu/libwbclient.so* /opt/smb-tools/lib/ || true + +# Debug-Ausgabe +/opt/smb-tools/bin/smbclient -V || true +ls -la /opt/smb-tools/bin /opt/smb-tools/lib || true diff --git a/k3s/apps/Nextcloud/helm/values-nextcloud.yaml b/k3s/apps/Nextcloud/helm/values-nextcloud.yaml new file mode 100644 index 0000000..d423efb --- /dev/null +++ b/k3s/apps/Nextcloud/helm/values-nextcloud.yaml @@ -0,0 +1,58 @@ +# Chart-internes Persistence deaktivieren (nicht ganzes Webroot mounten) +persistence: + enabled: false + +# Nextcloud Config +nextcloud: + host: 192.168.178.138 + username: admin + password: admin + datadir: /data + trustedDomains: + - 192.168.178.138 + - nextcloud.lan + - knode0 + + # PodSecurityContext wichtig für NFS (www-data ist UID/GID 33) + podSecurityContext: + fsGroup: 33 + +# Extra Volume nur für /data mounten +extraVolumes: + - name: nextcloud-data + persistentVolumeClaim: + claimName: nextcloud-data-pvc + +extraVolumeMounts: + - name: nextcloud-data + mountPath: /data + +# MariaDB intern +internalDatabase: + enabled: false + +mariadb: + enabled: true + architecture: standalone + auth: + database: nextcloud + username: nextcloud + password: nextcloud + rootPassword: "123456" + primary: + persistence: + enabled: true + storageClass: local-path + size: 10Gi + +# Redis +redis: + enabled: true + auth: + enabled: true + password: redis + master: + persistence: + enabled: true + storageClass: local-path + size: 1Gi \ No newline at end of file diff --git a/k3s/apps/Nextcloud/helm/values-nextcloud.yaml.bac b/k3s/apps/Nextcloud/helm/values-nextcloud.yaml.bac new file mode 100644 index 0000000..755fba2 --- /dev/null +++ b/k3s/apps/Nextcloud/helm/values-nextcloud.yaml.bac @@ -0,0 +1,91 @@ +global: + security: + allowInsecureImages: true + +image: + registry: docker.io + repository: library/nextcloud + flavor: apache + tag: "33.0.0-apache" + pullPolicy: IfNotPresent + +service: + type: NodePort + port: 80 + nodePort: 30180 + +internalDatabase: + enabled: false + +nextcloud: + username: "admin" + password: "admin" + + host: "192.168.178.138" + trustedDomains: + - "192.168.178.138" + - "nextcloud.lan" + - "knode0" + + persistence: + enabled: true + storageClass: local-path + accessMode: ReadWriteOnce + size: 5Gi + + # --- SMB "Nachinstallation" via ConfigMap + initContainer --- + extraVolumes: + - name: smb-tools + emptyDir: {} + - name: smb-install-script + configMap: + name: smb-install-script + defaultMode: 0755 + + extraVolumeMounts: + - name: smb-tools + mountPath: /opt/smb-tools + - name: smb-install-script + mountPath: /scripts + + extraInitContainers: + - name: install-smbclient + image: debian:bookworm-slim + imagePullPolicy: IfNotPresent + command: ["sh", "/scripts/install-smb.sh"] + volumeMounts: + - name: smb-tools + mountPath: /opt/smb-tools + - name: smb-install-script + mountPath: /scripts + + extraEnv: + - name: PATH + value: "/opt/smb-tools/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - name: LD_LIBRARY_PATH + value: "/opt/smb-tools/lib" + +mariadb: + enabled: true + architecture: standalone + auth: + database: nextcloud + username: nextcloud + password: "nextcloud" + rootPassword: "nextcloud" + primary: + persistence: + enabled: true + storageClass: local-path + size: 10Gi + +redis: + enabled: true + auth: + enabled: true + password: "redis" + master: + persistence: + enabled: true + storageClass: local-path + size: 1Gi \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/mariadb-deployment.yaml b/k3s/apps/Nextcloud/manifest/mariadb-deployment.yaml new file mode 100644 index 0000000..8eb9c2a --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/mariadb-deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mariadb + namespace: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app: mariadb + template: + metadata: + labels: + app: mariadb + spec: + containers: + - name: mariadb + image: mariadb:10.8 + imagePullPolicy: IfNotPresent + env: + - name: MYSQL_ROOT_PASSWORD + value: "123456" + - name: MYSQL_DATABASE + value: nextcloud + - name: MYSQL_USER + value: nextcloud + - name: MYSQL_PASSWORD + value: nextcloud + ports: + - containerPort: 3306 + volumeMounts: + - name: mariadb-data + mountPath: /var/lib/mysql + volumes: + - name: mariadb-data + persistentVolumeClaim: + claimName: pvc-mariadb \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/mariadb-pv-pvc.yaml b/k3s/apps/Nextcloud/manifest/mariadb-pv-pvc.yaml new file mode 100644 index 0000000..c777d52 --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/mariadb-pv-pvc.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pvc-mariadb + namespace: nextcloud +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: local-path # <-- explicit default StorageClass +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-mariadb + labels: + app: mariadb +spec: + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: local-path + claimRef: + namespace: nextcloud + name: pvc-mariadb + hostPath: + path: /var/lib/mariadb-data + type: DirectoryOrCreate diff --git a/k3s/apps/Nextcloud/manifest/mariadb-service.yaml b/k3s/apps/Nextcloud/manifest/mariadb-service.yaml new file mode 100644 index 0000000..d3fbad6 --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/mariadb-service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: mariadb + namespace: nextcloud +spec: + selector: + app: mariadb + ports: + - port: 3306 + targetPort: 3306 \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/nextcloud-deployment.yaml b/k3s/apps/Nextcloud/manifest/nextcloud-deployment.yaml new file mode 100644 index 0000000..8e44ae3 --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/nextcloud-deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nextcloud + namespace: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app: nextcloud + template: + metadata: + labels: + app: nextcloud + spec: + # fsGroup sorgt dafür, dass gemountete Volumes die Gruppe www-data (33) bekommen + securityContext: + fsGroup: 33 + containers: + - name: nextcloud + image: nextcloud:33-apache + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + env: + # - name: NEXTCLOUD_ADMIN_USER + # value: admin + # - name: NEXTCLOUD_ADMIN_PASSWORD + # value: admin + - name: MYSQL_HOST + value: mariadb.nextcloud.svc.cluster.local + - name: MYSQL_DATABASE + value: nextcloud + - name: MYSQL_USER + value: nextcloud + - name: MYSQL_PASSWORD + value: "nextcloud" + - name: REDIS_HOST + value: redis.nextcloud.svc.cluster.local + - name: NEXTCLOUD_TRUSTED_DOMAINS + value: "henryathome.home64.de,192.168.178.0/24,192.168.178.138" + # resources: + # requests: + # memory: "512Mi" + # cpu: "250m" + # limits: + # memory: "1Gi" + # cpu: "1000m" + volumeMounts: + - name: data + mountPath: /var/www/html/data # angepasst auf Standard Nextcloud Datadir + volumes: + - name: data + persistentVolumeClaim: + claimName: nextcloud-data-pvc \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/nextcloud-pv-pvc.yaml b/k3s/apps/Nextcloud/manifest/nextcloud-pv-pvc.yaml new file mode 100644 index 0000000..7e7b03c --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/nextcloud-pv-pvc.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-nextcloud-data-nfs +spec: + capacity: + storage: 500Gi + accessModes: + - ReadWriteMany + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs + mountOptions: + - vers=4 + - rsize=65536 + - wsize=65536 + - noatime + nfs: + server: 192.168.178.186 # <-- ERSETZEN: IP oder Hostname deiner NAS + path: /volume1/Nextcloud/data # <-- ERSETZEN: Pfad zum Share auf der NAS (z.B. /volume1/nextcloud) +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nextcloud-data-pvc + namespace: nextcloud +spec: + accessModes: + - ReadWriteMany + storageClassName: nfs + resources: + requests: + storage: 500Gi + volumeName: pv-nextcloud-data-nfs \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/nextcloud-service.yaml b/k3s/apps/Nextcloud/manifest/nextcloud-service.yaml new file mode 100644 index 0000000..50590b9 --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/nextcloud-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: nextcloud + namespace: nextcloud +spec: + type: NodePort + selector: + app: nextcloud + ports: + - port: 80 + targetPort: 80 + nodePort: 30180 \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/redis-deployment.yaml b/k3s/apps/Nextcloud/manifest/redis-deployment.yaml new file mode 100644 index 0000000..e729192 --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/redis-deployment.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:7.0 + ports: + - containerPort: 6379 + volumeMounts: + - name: redis-data + mountPath: /data + volumes: + - name: redis-data + emptyDir: {} \ No newline at end of file diff --git a/k3s/apps/Nextcloud/manifest/redis-service.yaml b/k3s/apps/Nextcloud/manifest/redis-service.yaml new file mode 100644 index 0000000..48cf24d --- /dev/null +++ b/k3s/apps/Nextcloud/manifest/redis-service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: nextcloud +spec: + selector: + app: redis + ports: + - port: 6379 + targetPort: 6379 \ No newline at end of file diff --git a/k3s/apps/Nextcloud/pv/pvc-nexcloud.yaml b/k3s/apps/Nextcloud/pv/pvc-nexcloud.yaml new file mode 100644 index 0000000..0aac316 --- /dev/null +++ b/k3s/apps/Nextcloud/pv/pvc-nexcloud.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nextcloud-data-pvc + namespace: nextcloud +spec: + accessModes: + - ReadWriteMany + storageClassName: nfs + resources: + requests: + storage: 500Gi + volumeName: pv-nextcloud-data-nfs \ No newline at end of file diff --git a/k3s/apps/photo/photoprism/photoprism.yaml b/k3s/apps/photo/photoprism/photoprism.yaml index 001c318..90d126d 100644 --- a/k3s/apps/photo/photoprism/photoprism.yaml +++ b/k3s/apps/photo/photoprism/photoprism.yaml @@ -76,7 +76,23 @@ spec: value: "true" - name: PHOTOPRISM_SIDECAR_JSON value: "true" - # resources: + - name: PHOTOPRISM_OIDC_URI + value: "https://authentik.henryathome.home64.de/application/o/photoprism/" + - name: PHOTOPRISM_OIDC_CLIENT + value: "UL29po2otoaH2mioipq9cekGkFSUvX6hTywaRsZ6" + - name: PHOTOPRISM_OIDC_SECRET + value: "Dx1FXPuFMtDFliZaZbpCOnlYvJYsFiBW533IyeRVdsT4y6XIAsHKVtLFYBijLXVQElu0UqoGOF1JJ8E2Gy3v97chQf6kXBQ5T2UMOXeFWSUlzhXVbNTFGwhITqPizycv" + - name: PHOTOPRISM_OIDC_PROVIDER + value: authentik + - name: PHOTOPRISM_OIDC_REDIRECT + value: "true" + - name: PHOTOPRISM_OIDC_REGISTER + value: "true" + - name: PHOTOPRISM_OIDC_ICON + value: "/static/img/oidc.svg" + - name: PHOTOPRISM_OIDC_USERNAME + value: "email" + resources: # requests: # cpu: "100m" # memory: "128Mi"