diff --git a/kubernetes/app/lubelogger/MIGRATION.md b/kubernetes/app/lubelogger/MIGRATION.md new file mode 100644 index 0000000..09119da --- /dev/null +++ b/kubernetes/app/lubelogger/MIGRATION.md @@ -0,0 +1,127 @@ +# LubeLogger Migration: Docker → Kubernetes + +## Overview + +LubeLogger is migrated from a single Docker container using LiteDB (SQLite-like embedded DB) to +Kubernetes with PostgreSQL as the data store. The migration involves: + +1. Copying app data (images, documents, config) from the Docker host to NFS +2. Running the built-in database migration UI to import records from LiteDB → PostgreSQL + +## Source Layout (Docker) + +| Container Path | Docker Source | +|---|---| +| `/App/data` | `/home/server/docker/lubelogger/data` on Docker host | +| `/root/.aspnet/DataProtection-Keys` | `/home/server/docker/lubelogger/keys` on Docker host | + +The `/App/data` directory contains: +- `cartracker.db` — LiteDB database with all vehicle/maintenance records +- `images/` — uploaded vehicle images +- `documents/` — uploaded maintenance documents + +## Target Layout (Kubernetes) + +| Container Path | Kubernetes PVC | +|---|---| +| `/App/data` | `lubelogger-data` PVC → NFS `/volume3/k8s-storage/lubelogger-data` | +| `/root/.aspnet/DataProtection-Keys` | ephemeral (pod filesystem) — losing keys only invalidates sessions | + +PostgreSQL data is managed by the `lubelogger-db` StatefulSet with its own `nfs-synology-ssd` PVC. + +## Prerequisites + +- NFS directory created on Synology: `/volume3/k8s-storage/lubelogger-data` +- Secrets filled in and encrypted (see TODO.md) +- PostgreSQL restic repos initialized on Synology and B2 + +## Step-by-Step Migration + +### 1. Deploy with replicas: 0 + +Ensure `statefulset-db.yaml` has `replicas: 1` (PostgreSQL must be running) but set the +LubeLogger Helm release to `replicaCount: 0` before the first commit. After Flux applies, +all PVCs will be created and bound. + +Actually: PostgreSQL starts at replicas: 1. The app (HelmRelease) starts at replicas: 1 by default +from the chart. Since we want to run the migration UI, we need the app running. Scale to 1 normally. + +### 2. Wait for PVCs to bind + +```bash +kubectl get pvc -n lubelogger +``` + +All should be `Bound`. The `lubelogger-data` PVC binds to the static NFS PV automatically. + +The PostgreSQL PVC name is `data-lubelogger-db-0` (StatefulSet volumeClaimTemplate naming). + +### 3. Stop Docker service + +```bash +# On the Docker host +cd /path/to/lubelogger-compose +docker compose stop app +# Keep DB stopped too since we're going to PostgreSQL +``` + +### 4. Copy app data to NFS + +```bash +# Create the NFS directory on Synology if not done already +mkdir -p /volume3/k8s-storage/lubelogger-data + +# Copy from Docker host to Synology NFS path +# Run from the Docker host (or any machine with SSH access to both): +rsync -av /home/server/docker/lubelogger/data/ synology:/volume3/k8s-storage/lubelogger-data/ +``` + +The `cartracker.db` file is copied too — it's needed for the migration step. + +### 5. Run the LiteDB → PostgreSQL migration + +Once the Kubernetes app is running and PostgreSQL is ready: + +```bash +# Verify LubeLogger pod is running +kubectl get pods -n lubelogger + +# Verify PostgreSQL is up +kubectl exec -n lubelogger lubelogger-db-0 -- psql -U lubelogger -c '\l' +``` + +Navigate to `https://lubelogger.berezovskyi.dev/migration` in your browser. + +1. Click **"Import to Postgres"** +2. Upload the `cartracker.db` file from your local copy of `/home/server/docker/lubelogger/data/` +3. LubeLogger will import all records automatically + +### 6. Verify migration + +- Check all vehicles appear +- Check maintenance records +- Check images and documents load +- Log in via Authelia OIDC + +## Verification Checklist + +- [ ] All pods running: `kubectl get pods -n lubelogger` +- [ ] LubeLogger web UI loads at `https://lubelogger.berezovskyi.dev` +- [ ] Authelia OIDC login works +- [ ] All vehicles visible with correct data +- [ ] Maintenance history records intact +- [ ] Images load (stored in NFS `/App/data/images/`) +- [ ] Documents accessible +- [ ] Test backup: `kubectl create job -n lubelogger --from=cronjob/lubelogger-db-backup test-db-backup` + +## Rollback + +1. Scale HelmRelease to 0: edit `release.yaml` → `replicaCount: 0`, commit, push +2. Restart Docker service: `docker compose start app` +3. The Docker install still has its LiteDB database intact + +## Notes + +- The Authelia OIDC client was already configured at `lubelogger.berezovskyi.dev` — no changes needed +- DataProtection keys are intentionally ephemeral: users will need to log in again after pod restarts +- After confirming the migration is complete, the `cartracker.db` in the NFS data directory can be deleted (it is no longer used once PostgreSQL is the backend) diff --git a/kubernetes/app/lubelogger/cronjob-backup.yaml b/kubernetes/app/lubelogger/cronjob-backup.yaml new file mode 100644 index 0000000..088422d --- /dev/null +++ b/kubernetes/app/lubelogger/cronjob-backup.yaml @@ -0,0 +1,156 @@ +--- +# PostgreSQL database backup +apiVersion: batch/v1 +kind: CronJob +metadata: + name: lubelogger-db-backup + namespace: lubelogger + labels: + app: lubelogger-backup +spec: + schedule: "0 2 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + metadata: + labels: + app: lubelogger-backup + spec: + restartPolicy: OnFailure + initContainers: + - name: pg-dump + image: postgres:18 + env: + - name: PGHOST + value: lubelogger-db + - name: PGUSER + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_USERNAME + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_PASSWORD + - name: PGDATABASE + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_DATABASE_NAME + command: + - sh + - -c + - pg_dump --clean --if-exists > /backup/dump.sql + volumeMounts: + - name: backup-tmp + mountPath: /backup + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + memory: 256Mi + containers: + - name: resticprofile + image: creativeprojects/resticprofile:0.32.0 + command: + - sh + - -c + - | + resticprofile -c /secrets/profiles.yaml -n lubelogger-db backup + resticprofile -c /secrets/profiles.yaml -n lubelogger-db copy + env: + - name: B2_ACCOUNT_ID + valueFrom: + secretKeyRef: + name: lubelogger-backup-config + key: B2_ACCOUNT_ID + - name: B2_ACCOUNT_KEY + valueFrom: + secretKeyRef: + name: lubelogger-backup-config + key: B2_ACCOUNT_KEY + volumeMounts: + - name: secrets + mountPath: /secrets + readOnly: true + - name: backup-tmp + mountPath: /backup + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + volumes: + - name: secrets + secret: + secretName: lubelogger-backup-config + - name: backup-tmp + emptyDir: {} +--- +# App data backup (images, documents) +apiVersion: batch/v1 +kind: CronJob +metadata: + name: lubelogger-data-backup + namespace: lubelogger + labels: + app: lubelogger-backup +spec: + schedule: "0 3 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + metadata: + labels: + app: lubelogger-backup + spec: + restartPolicy: OnFailure + containers: + - name: resticprofile + image: creativeprojects/resticprofile:0.32.0 + command: + - sh + - -c + - | + resticprofile -c /secrets/profiles.yaml -n lubelogger-data backup + resticprofile -c /secrets/profiles.yaml -n lubelogger-data copy + env: + - name: B2_ACCOUNT_ID + valueFrom: + secretKeyRef: + name: lubelogger-backup-config + key: B2_ACCOUNT_ID + - name: B2_ACCOUNT_KEY + valueFrom: + secretKeyRef: + name: lubelogger-backup-config + key: B2_ACCOUNT_KEY + volumeMounts: + - name: secrets + mountPath: /secrets + readOnly: true + - name: data + mountPath: /data + readOnly: true + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + volumes: + - name: secrets + secret: + secretName: lubelogger-backup-config + - name: data + persistentVolumeClaim: + claimName: lubelogger-data diff --git a/kubernetes/app/lubelogger/deployment.yaml b/kubernetes/app/lubelogger/deployment.yaml deleted file mode 100644 index e69ede8..0000000 --- a/kubernetes/app/lubelogger/deployment.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: lubelogger - name: lubelogger - namespace: lubelogger -spec: - replicas: 1 - selector: - matchLabels: - app: lubelogger - template: - metadata: - labels: - app: lubelogger - spec: - containers: - - image: ghcr.io/hargata/lubelogger:latest - name: lubelogger - ports: - - containerPort: 8080 - volumeMounts: - - name: data - mountPath: /App/data - - name: keys - mountPath: /root/.aspnet/DataProtection-Keys - volumes: - - name: data - persistentVolumeClaim: - claimName: lubelogger-data - - name: keys - persistentVolumeClaim: - claimName: lubelogger-keys diff --git a/kubernetes/app/lubelogger/ingress.yaml b/kubernetes/app/lubelogger/ingress.yaml deleted file mode 100644 index f5b47d3..0000000 --- a/kubernetes/app/lubelogger/ingress.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: lubelogger - namespace: lubelogger - annotations: - cert-manager.io/cluster-issuer: letsencrypt -spec: - tls: - - hosts: - - ${LUBELOGGER_HOST} - secretName: lubelogger-tls - rules: - - host: ${LUBELOGGER_HOST} - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: lubelogger - port: - number: 8080 diff --git a/kubernetes/app/lubelogger/namespace.yaml b/kubernetes/app/lubelogger/namespace.yaml index 475def3..617af9e 100644 --- a/kubernetes/app/lubelogger/namespace.yaml +++ b/kubernetes/app/lubelogger/namespace.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Namespace metadata: diff --git a/kubernetes/app/lubelogger/networkpolicy.yaml b/kubernetes/app/lubelogger/networkpolicy.yaml new file mode 100644 index 0000000..7e05e68 --- /dev/null +++ b/kubernetes/app/lubelogger/networkpolicy.yaml @@ -0,0 +1,100 @@ +# Default deny all ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny-ingress + namespace: lubelogger +spec: + podSelector: {} + policyTypes: + - Ingress +--- +# Allow Traefik to reach the app +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-ingress-controller + namespace: lubelogger +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: lubelogger + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: traefik +--- +# Allow app to reach DB +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-app-to-db + namespace: lubelogger +spec: + podSelector: + matchLabels: + app: lubelogger-db + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: lubelogger + ports: + - port: 5432 +--- +# Allow backup pods to reach DB +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-backup-to-db + namespace: lubelogger +spec: + podSelector: + matchLabels: + app: lubelogger-db + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: lubelogger-backup + ports: + - port: 5432 +--- +# Allow backup pods egress (Synology, B2, DNS, DB) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-backup-egress + namespace: lubelogger +spec: + podSelector: + matchLabels: + app: lubelogger-backup + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - ports: + - port: 8888 + protocol: TCP + - ports: + - port: 443 + protocol: TCP + - ports: + - port: 5432 + protocol: TCP + to: + - podSelector: + matchLabels: + app: lubelogger-db diff --git a/kubernetes/app/lubelogger/pv.yaml b/kubernetes/app/lubelogger/pv-data.yaml similarity index 52% rename from kubernetes/app/lubelogger/pv.yaml rename to kubernetes/app/lubelogger/pv-data.yaml index b01cff4..64bd8f2 100644 --- a/kubernetes/app/lubelogger/pv.yaml +++ b/kubernetes/app/lubelogger/pv-data.yaml @@ -1,35 +1,32 @@ apiVersion: v1 kind: PersistentVolume metadata: - name: lubelogger-data + name: lubelogger-data-nfs spec: capacity: - storage: 1Gi + storage: 5Gi accessModes: - ReadWriteOnce storageClassName: "" persistentVolumeReclaimPolicy: Retain mountOptions: - hard - - nointr + - timeo=30 + - retrans=3 nfs: server: synology.storage.lviv - path: /volume3/k8s-storage/lubelogger-data + path: ${LUBELOGGER_DATA_NFS_PATH} --- apiVersion: v1 -kind: PersistentVolume +kind: PersistentVolumeClaim metadata: - name: lubelogger-keys + name: lubelogger-data + namespace: lubelogger spec: - capacity: - storage: 1Gi accessModes: - ReadWriteOnce storageClassName: "" - persistentVolumeReclaimPolicy: Retain - mountOptions: - - hard - - nointr - nfs: - server: synology.storage.lviv - path: /volume3/k8s-storage/lubelogger-keys + volumeName: lubelogger-data-nfs + resources: + requests: + storage: 5Gi diff --git a/kubernetes/app/lubelogger/pvc.yaml b/kubernetes/app/lubelogger/pvc.yaml deleted file mode 100644 index a15c01f..0000000 --- a/kubernetes/app/lubelogger/pvc.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: lubelogger-data - namespace: lubelogger -spec: - accessModes: - - ReadWriteOnce - storageClassName: "" - volumeName: lubelogger-data - resources: - requests: - storage: 1Gi ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: lubelogger-keys - namespace: lubelogger -spec: - accessModes: - - ReadWriteOnce - storageClassName: "" - volumeName: lubelogger-keys - resources: - requests: - storage: 1Gi diff --git a/kubernetes/app/lubelogger/release.yaml b/kubernetes/app/lubelogger/release.yaml new file mode 100644 index 0000000..79924aa --- /dev/null +++ b/kubernetes/app/lubelogger/release.yaml @@ -0,0 +1,84 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: lubelogger + namespace: flux-system +spec: + chart: + spec: + chart: lubelogger + version: 1.4.2 + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: anza-labs + namespace: flux-system + targetNamespace: lubelogger + interval: 1m0s + values: + image: + tag: "v1.6.1" + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 100% + + config: + LANG: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LOGLEVEL: Information + translations: [] + userConfig: + AllowedHosts: "*" + EnableAuth: true + UseDarkMode: false + EnableCsvImports: true + UseMPG: false + UseDescending: true + UseThreeDecimalGasCost: true + + postgres: + create: false + connect: true + name: lubelogger-credentials + keyRef: POSTGRES_CONNECTION + + oidc: + enabled: true + create: false + name: lubelogger-credentials + + secret: + create: false + + persistence: + data: + enabled: true + existingClaim: lubelogger-data + + ingress: + enabled: true + className: "" + annotations: + cert-manager.io/cluster-issuer: letsencrypt + hosts: + - host: ${LUBELOGGER_HOST} + paths: + - path: / + pathType: Prefix + tls: + - secretName: lubelogger-tls + hosts: + - ${LUBELOGGER_HOST} + + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + + podSecurityContext: + seccompProfile: + type: RuntimeDefault diff --git a/kubernetes/app/lubelogger/repository.yaml b/kubernetes/app/lubelogger/repository.yaml new file mode 100644 index 0000000..410478c --- /dev/null +++ b/kubernetes/app/lubelogger/repository.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: anza-labs + namespace: flux-system +spec: + interval: 1m0s + url: https://anza-labs.github.io/charts diff --git a/kubernetes/app/lubelogger/secret-backup.sops.yaml b/kubernetes/app/lubelogger/secret-backup.sops.yaml new file mode 100644 index 0000000..05028c3 --- /dev/null +++ b/kubernetes/app/lubelogger/secret-backup.sops.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Secret +metadata: + name: lubelogger-backup-config + namespace: lubelogger +stringData: + profiles.yaml: ENC[AES256_GCM,data:ry4ry1yf+KgUP6D2WzIUaGCPCvsJ8CKjAjJtlMDhHh55KrMEpwmWiHYIaHzRJtYkGpou/mxKyGdPAIDfo2h2teNmBd9sbHd3/FaR5USHqzd+LNhn5LN1aeQ5H7vzFzZj0JVjUwQ6SxppxmW7/kDKFHfTB/QXYchz2QdFtRrBiaXRd0SMYDA7DDLFbGG6x3oxbywpmA5jdojHw/2a18S4eSoLzYZnZZvNR5pMXmmzBUWJ0xBd7t3uzx1MuP+a/tAlalFXcoUg3hH+yFvgF9gb4gxqlDNyvsCBq3klVN43mGYdzC7gzuYGGi5BV8NZ/THSapOsapbux6LbUVebxbt2l2XLv0IoPxZCYKZ0RbA+Of6Fp2tlCekKNey5H2mviPHrjkipt+o7FcNXISSE8k6siky8ouiXFB6Hr/SEZs91i1jgxG1Xwpt7nNSNt2XB2IPjnCSvpAvYW/KlOf880lh7/xmpk5O0Xa4BRF1Hfn/EmsR8HL5q8dSV9OcYUKcIZVMvXFOI+yu10GpkIbueuMuOeFyUUBh3TGJKIJElHzxwDXC5YrqtT3GOphFGnQ+cN1ZHDsywe0Q5wDMxPPGEh6SL/7OpSN5loUZ5MoC65lkVzEQZewG0RBjgiZSIJsCUlIKdmt5AfokXjXxUmb8/qPEVyvL/ltFdzFIiGJcAnlRsM1ltFcrxGr+N6bnr1jyoS6xk5b4QWCJKWhJt4ITeoHZzN9liWOEpKxhYWpN2wlkmpmTgXIVhzi1bR15s7ZX+XbQi9X6iVwGZiJ6T3HLb4BeWo6YvtqebU3fIJabWHr9I956OU8+F8uCLFJjUXUYoT0ww50wsNix0C2PNovNv7SGQO+GH1F7sU6EYJAqKBXZRMF49NCuyAiK9uB5N2xKqh0eEtmGvO/U38ihs1OPZtCzwNg/xo5OHAoJWx09BE8+YR7KRmIh/AJHR6Jfb9JPCb8Qz8iNBMhtxJk2l6clZKMnBNckHk97mGYELFyTPlsVDnHIxWIokMshHxhCtuT/OaxsZawzAUYQ8Tz4TLei1/iTS97wn2AyeF4L6yPSQfYbZWu4mwsuQ2zr3VCmnbzsMomihJgiELSpcoXqh7GEc4FPbhXWBUfdJH1DA9jH/E4LpNnwX1g5bs1cphK6nkcaU6pbsEYiEktvpCV1Vyd9rxcHEIkCVQnLkUZPRIXaW/+7+TQPtKVjvOc33SjTrQJNLuZ2zd0mxrJAforagMZHENBJpefHe4dzy1farKTTccTCCbzVjXkz4+QyjDdI9Qjq+HfPJ5ajrO4mgudNazAJuBWc=,iv:BUdGosePz+FW9bqLuJhSaIMbU0N/2UVjmSJVEAwbk8c=,tag:So7no71/2ypFkyVadF9myg==,type:str] + restic-password-nas: ENC[AES256_GCM,data:qhOYuyEjbX4lqOzQM+T+pQEWxm8LqTy/yskxw9tl6bMz0OnwbkdJ87TVqUV99TRbRteoNfEnbUec3P/w2H4LVw==,iv:Ge5RiXnavsohOfh90Nn2cmdvY4qapK5QYoC8O13j52E=,tag:NjRsyb/F7sMd/UBZr3PIAg==,type:str] + restic-password-b2: ENC[AES256_GCM,data:emCXooHFBUTBN0fuVN+bG2LfYcoxDr6vYEWNV/4A9Eru/cXXwfvzQQOasmRKVxtd13AmtQlZMY7MgTg1cvackw==,iv:rzYf2hA3/MDz8eVn9NrgjTEA0+qhKcrtGGvEIITfJws=,tag:n/PP2R81FH6WfvOQsZyejw==,type:str] + B2_ACCOUNT_ID: ENC[AES256_GCM,data:5emkgkrSMlo9SAcMgjLtu4TiRMxi4GGxng==,iv:bhaBY5vZey6+bz1/xje3CGznWh4XoFBEPAaYYdhipbs=,tag:DzPTv9gyCiuuRuiot7eshg==,type:str] + B2_ACCOUNT_KEY: ENC[AES256_GCM,data:M5r+drnI7MyvYs5XpAbvyZbEDuY4hQCgQEgwpQO8JQ==,iv:fKEDq2fqpOdn3WqSN8YcBK2/7cNgLkAfDewzuuInVYE=,tag:NuWBKr7J/asYgqa8e5xrHg==,type:str] +sops: + age: + - recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJK09RUldOZVdNSENrQ0J0 + cHU3dWlVYnllV3RmWUFTdUM0U0ZLeHpwN1hBCmZ4TTMyVy9FMEtGcWRRUzUzWHpN + bnhiNHZZbWVzelNqNXVTUlBDYzlpUEUKLS0tIEFGOXhNN0pIeXpiZ29LdTB4Vm9T + REdCTDVUSjVGbFh6aGlhUFVFR3VhazAKLpa4UUq4ev4IvexmhVcZm9UJl15bi4TZ + /AM7PcY1khK48OJA2QczOXpL6VkKin5YY3zUBmU388boVgWNPU7ygw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-12T17:28:48Z" + mac: ENC[AES256_GCM,data:33oz/vhF702e0a4JdGoQ6iM0huUufXlQS69o2dCemASpDpfl4+fl1N0e4KWM16WiVkN2PV1Tbc/nPa+0nZ6rIg3XZwnVY9Zemr3WNfMHEtodJRxN4WZPQ3sJ2rRAfGTus2SnYFs2mHYXPHzyY6aFBUKfEExbUL7UU2wQ1UmK1H4=,iv:0QisSz8NnEL09q8z8I5BtkdcDjO5yOF9XZhMyagxNxc=,tag:3JGHRQl5P9uKS5xQ+jBdIg==,type:str] + encrypted_regex: ^(data|stringData|email)$ + version: 3.12.1 diff --git a/kubernetes/app/lubelogger/secret-mail.sops.yaml b/kubernetes/app/lubelogger/secret-mail.sops.yaml new file mode 100644 index 0000000..560fbcd --- /dev/null +++ b/kubernetes/app/lubelogger/secret-mail.sops.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Secret +metadata: + name: lubelogger-lubelogger-mail + namespace: lubelogger +stringData: + MailConfig__EmailServer: "" + MailConfig__EmailFrom: "" + MailConfig__Port: ENC[AES256_GCM,data:BAtd,iv:i5Q/4OONVm0c7wZe8JvKnF/bMSH9bh8XY4+2xwGh36E=,tag:i+q0spj4URbiShtEvnbghQ==,type:str] + MailConfig__Username: "" + MailConfig__Password: "" +sops: + age: + - recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5M2loaXBwVmMrcHBUaTJV + Smp0bURnUWh6ZjFUcUhFc3p4ZGxGVHlMbUc4Cm4vdnBvOS9zeVBDVE84dkEzek9N + Y3ROelkxY3A3cXN5ODZ4RHZEd2c1YWcKLS0tIDZPZEQ4cVQwcldscDdaeVJzMTBI + emlNNUFSOERJeEdNSkdpdEs0QVUralkKN9aSdQnGXGzLrZfCOFO1VgSAOC5PWkE8 + HRB6woNiTVPTgwObG+7u8/IxLN/WdwAGjx3ETBMys4BYk2QhjLkADg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-12T17:41:00Z" + mac: ENC[AES256_GCM,data:bLdSIuaRXGcGRjnIuboJnRkabuNUno8OjeQQYaYUkLzmIv1ukAAVismMfCUKLcN3ZaqsNPwjfnRrpLA4YWiS4aN9Nk5fCL8QMBe49CwITytrtZkaxtUIn/TC0U8G+KGT4YSmv6XPoai37B48zdqVnard0OqwWItcgv+le9l0ozI=,iv:YU1JgWt/jfRSoZPzvc4+ffsR4sPbcjgbdsh1P+g8lTo=,tag:85SfU3FQUpqW5ALV24rEMw==,type:str] + encrypted_regex: ^(data|stringData|email)$ + version: 3.12.1 diff --git a/kubernetes/app/lubelogger/secret.sops.yaml b/kubernetes/app/lubelogger/secret.sops.yaml new file mode 100644 index 0000000..8b69cad --- /dev/null +++ b/kubernetes/app/lubelogger/secret.sops.yaml @@ -0,0 +1,44 @@ +apiVersion: v1 +kind: Secret +metadata: + name: lubelogger-credentials + namespace: lubelogger +stringData: + #ENC[AES256_GCM,data:q8YkSYhUjXayq4c/v9q014si6MiQwH//1AD04/j0hxwUyH/Kr2Z+Q1vw9g/qWo/19cxBWPkt1NkY,iv:2kdJLLw4epkN0ZymXumUBpo1U5RSpgDfVftslovvAMk=,tag:upMo0Mk+STLa0XxgQ6dYeQ==,type:comment] + DB_USERNAME: ENC[AES256_GCM,data:eogW0ytMfVFp9g==,iv:5SCxLHVSiuWekj2Z9DzoVFNphK8lap4DbGJEtuKlE/g=,tag:DXy9H0dhAaOVIGP0IzmOyQ==,type:str] + DB_PASSWORD: ENC[AES256_GCM,data:eokX9Zf/HCBDXPvggJvAdnYMZtpfeGA3KOUP99CGZrbpsuibWSYNBCZRSVppSMU++el71rgxsuNe7GiOLjJkSg==,iv:+/vsYNdqW5OLZe2cQAeG16x39wAdnUD7O3iv3JfY6PA=,tag:M3z9yUcr8njY7n4eJvQKVg==,type:str] + DB_DATABASE_NAME: ENC[AES256_GCM,data:rBl/9lzfihT5Cw==,iv:bIAa2b1+AJH8pAmFUEPe8bbDw0aV+wRmgnjTZ4KhbHc=,tag:Zf/KruFw0IGj39A5v0g2sQ==,type:str] + #ENC[AES256_GCM,data:chnWZQLNaZdeX0+nNG8OJnVuDktWKFjxs01U1ErzIrpYLILlROOnVxPq6xnkLGz2LSaBbw6HSfU=,iv:xrHMQ78h04edxwRvhgHYUfMWp76UgM0+mQkS4OQszRg=,tag:99pUo39fOHjYFEVYqQkWEQ==,type:comment] + POSTGRES_CONNECTION: ENC[AES256_GCM,data:qiXHM0OI/bb24TM4OtcYmRt7UiyZ0phkQ5WJ4io/1sPKD6nPj/g6IbF03V8fAejApzNPkBpGtPTQbF1QhiHLZvRa530lWlcfXvj5nu0ZLhqJ/cGQ1nv1mNoSAE8QpbqxtJ/K3M1fl0M4nvkeH/xEj7VOcOJ0acAFjjmhWNR3qQgkjhwgtfKuMSrj,iv:/cK1H8YOVPOW8hA2NlyD2ihsmsqI7xMejCont0SwNFM=,tag:rjQ89vFDzRuDFB83txRYfw==,type:str] + #ENC[AES256_GCM,data:I8lMrioI4WHL3E3kuGIvuaZWk0bF8C4F4Hql1seJrz2EOOfZ8os9RX5GDPVnzUanH+OxXQy2FQ5GaGSS8hz+VF8=,iv:yV5mo7iDFV44ioj7AvNo+Vt0/DdeCOqZJeuykA/RONU=,tag:82+jBpVf/Iz6UD5bNDdPLA==,type:comment] + OpenIDConfig__Name: ENC[AES256_GCM,data:EgLPMKKWvtQ=,iv:9oQiLXbv/Z3s+nXfCzIX/wgrptz66vwJiQnvX85sF2g=,tag:9crlLAiGwrWGxuZAAr6fxQ==,type:str] + OpenIDConfig__ClientId: ENC[AES256_GCM,data:RX4Upr/Y9VcE8g==,iv:WkjziuLRuAsiNqfqgw00KHflRb7u57LVIQuYlEwvAGc=,tag:rWhjbdSx63d8iiMCgSt2hA==,type:str] + OpenIDConfig__ClientSecret: ENC[AES256_GCM,data:J5LSBhRUVQ8ySEpHZgy0FWTyQz14dJUSwT2IXQFnsGjHqQfsxXKRN5bIh4qTCOrMTa+L7vcPUk00wiUqJAsRyHIdUhWqutb5,iv:vLkjOyvvVmqlOi1cbs0QSpAMLWTDaXGXl+Bc7zIkNYU=,tag:Je2cH9kDNzzkSxKNHqOb0Q==,type:str] + OpenIDConfig__AuthURL: ENC[AES256_GCM,data:ECZF4cUaiBb9WgDS6bq5azkpWhuRBy4Lbzs5FwpCdpUOzYddlkp3vZN4I8PkDYt4JMZ5XKEs,iv:2P24/H1FhHzimZDYCAHoyxTLyaS4ETuiAICwFwoDqyo=,tag:R63yiGpo5TF+kWxWXMIlPQ==,type:str] + OpenIDConfig__TokenURL: ENC[AES256_GCM,data:G03Uow5kKfjDwqG472sm86d7GgpsmZ4jFKTjrfC5SC2EwIMMAm0TxEb26lV3wg==,iv:77R5/h/Z+mipmp88M6P0qd3fdLaRqmNv1K8SzuGoGg0=,tag:fDA/b+/Rb4dZ/oSKlDlAzQ==,type:str] + OpenIDConfig__RedirectURL: ENC[AES256_GCM,data:pbOS6LCe65QAP45rnnuJAXiuDwAR/8pzanNJKk5ia4BO2Mk3s/4/6csvPA==,iv:0MCYj9rE1TUxJQ2zN0g2UAbAGK/7O89pkbPEwm9qAI4=,tag:byM6tFlmS8SAZDyLiayJFA==,type:str] + OpenIDConfig__Scope: ENC[AES256_GCM,data:JnXTW0PS0a0ShLVg+93MFF4OqPw=,iv:CXKuW9WOx9oPs7yIP07RVgk+fyrkJ6uQmVuxh9chXMg=,tag:MmgWGOFYCR6vF4DGftObUw==,type:str] + OpenIDConfig__ValidateState: ENC[AES256_GCM,data:xfeRVQ==,iv:YXeNyG4zqy7/MWBZVBOgu2tPOIaS+sDFsHHCtt0bUcg=,tag:ySDP5mSoQpy7N1lh6klT6Q==,type:str] + OpenIDConfig__UsePKCE: ENC[AES256_GCM,data:S3ReXQ==,iv:0ZG4KolJ8lQ7CFelr65ZMGwpFVV8UrewC+om5A6n1M0=,tag:p6ASno+y7XptZEElFD8b9w==,type:str] + OpenIDConfig__DisableRegularLogin: ENC[AES256_GCM,data:/fRFow==,iv:Gpy/YT2ucTZYhs5fm8eb2zakZ5LLsRoY027nRuB7X4A=,tag:klios0Pqo13UV21eDsM2LQ==,type:str] + OpenIDConfig__UserInfoURL: ENC[AES256_GCM,data:adn2dAYWwQWCBy+hb8MmkHsG8IV1UTJK5pKC7G9gTJao/X16bifniMKgfVX1mTpWhQ==,iv:o9lm6RwiLaZDKJHTUY+lTAyKXg0FPsoizMeuAhFlHSE=,tag:fVGYK8yDAgT8ztEVlq+glg==,type:str] + OpenIDConfig__LogOutURL: ENC[AES256_GCM,data:ugvDXxINUuTkLicLcfZ50XyzXBIrCp2HXU+CYMxX0hu+bDA3vyo=,iv:ZWqQ+lPnEV8vjPjZDYy2ws5J4ZumeGAJ5wW1Y+0rk1g=,tag:AiwMUGQppa/M2zCMUcBGCw==,type:str] + EnableAuth: ENC[AES256_GCM,data:oocLtw==,iv:peSI/7zKYld+iySbqV4OX2Q4YJbHePv9K7eEmXV78GI=,tag:qdTcHLjVINMxMZHN/C2RbQ==,type:str] + EnableRootUserOIDC: ENC[AES256_GCM,data:H/YHUw==,iv:88BYn3MeePmUy+2Z+DctMx4Gx/0AXKPKQDThliSrmcw=,tag:2moLxirbot9HArcLliRb4A==,type:str] + DefaultReminderEmail: ENC[AES256_GCM,data:wl2nfvSdSN0v1rM2ZiC4jYR5ba16hAgazQ==,iv:o638Gcgax5Z87xUUxQ+hvLrio8qpg6Ikq7V0pC9iB74=,tag:6ghl4RcMEAevGlRLmngMvQ==,type:str] + LUBELOGGER_OPEN_REGISTRATION: ENC[AES256_GCM,data:qpQuKzY=,iv:rTwdoAyu6QXf4qKL2ATuCTO847X0VjKb3Rl1q+O49qc=,tag:XLyMRYW6iEZG3QoFeSgH9w==,type:str] +sops: + age: + - recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFOWI2ZW9OSG9pS0xFdlFt + cWVVaVNNeUNrcFR0Qm5jSGFjK2lzNHRabm5rCjgrN2xDZXdmeHdSUTk3cHk5QUlk + TDFmUGNydWNwS1B1TjdIeFgzbnZmczAKLS0tIG0wM3hqY2F3UXRiODRUTGdVRGYz + ZVpEL0I5WlM1UjRya3F0akdzdzBxVXMKCyXCgwv4SVwKASE/rUrHg17iuNdykk/d + rixoJvG3XPXWLcAGLn14hrE0uAs4Oha27eW3psjae7/0UEgcUOvAag== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-12T18:01:33Z" + mac: ENC[AES256_GCM,data:KpkIviq319M4o9igUXKkBpzCfetySjxsL75HMh7r66C8I9vnxVdKQcMYXGiGtBWdSmYincxY49O0qnxr3oDzSIEgcIq6dE4AGXgWSMaJ837QbbIUG8MhEo6HRAUU2UB+ixiDPGBafu8Fna7b3HMVXSQN6BFr7kSIKWlhv/njyyA=,iv:ERQnyXxkUUm93le2CxBmqXN7MooWV7I26uXSOL2QstU=,tag:xvtBJxwLLpOIBKqhrOlNPw==,type:str] + encrypted_regex: ^(data|stringData|email)$ + version: 3.12.1 diff --git a/kubernetes/app/lubelogger/service-db.yaml b/kubernetes/app/lubelogger/service-db.yaml new file mode 100644 index 0000000..04bc48e --- /dev/null +++ b/kubernetes/app/lubelogger/service-db.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: lubelogger-db + namespace: lubelogger +spec: + clusterIP: None + selector: + app: lubelogger-db + ports: + - port: 5432 + targetPort: 5432 diff --git a/kubernetes/app/lubelogger/service.yaml b/kubernetes/app/lubelogger/service.yaml deleted file mode 100644 index 573e258..0000000 --- a/kubernetes/app/lubelogger/service.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: lubelogger - name: lubelogger - namespace: lubelogger -spec: - ports: - - name: 8080-8080 - port: 8080 - protocol: TCP - targetPort: 8080 - selector: - app: lubelogger - type: ClusterIP - diff --git a/kubernetes/app/lubelogger/statefulset-db.yaml b/kubernetes/app/lubelogger/statefulset-db.yaml new file mode 100644 index 0000000..e0ddce4 --- /dev/null +++ b/kubernetes/app/lubelogger/statefulset-db.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: lubelogger-db + namespace: lubelogger + labels: + app: lubelogger-db +spec: + serviceName: lubelogger-db + replicas: 1 + selector: + matchLabels: + app: lubelogger-db + template: + metadata: + labels: + app: lubelogger-db + spec: + securityContext: + runAsUser: 999 + runAsGroup: 999 + fsGroup: 999 + seccompProfile: + type: RuntimeDefault + containers: + - name: postgres + image: postgres:18 + env: + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_USERNAME + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_PASSWORD + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: lubelogger-credentials + key: DB_DATABASE_NAME + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + ports: + - containerPort: 5432 + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: ["ReadWriteOnce"] + storageClassName: nfs-synology-ssd + resources: + requests: + storage: 5Gi diff --git a/kubernetes/config/cluster-vars.sops.yaml b/kubernetes/config/cluster-vars.sops.yaml index 85a7af1..74e502c 100644 --- a/kubernetes/config/cluster-vars.sops.yaml +++ b/kubernetes/config/cluster-vars.sops.yaml @@ -4,42 +4,43 @@ metadata: name: cluster-vars namespace: flux-system stringData: - LUBELOGGER_HOST: ENC[AES256_GCM,data:S47mePYIuPOFXExqHCdbP5CcuPb/hqgA4/X8s1Js,iv:uHN/BO5eGr0hWTzUyOfza2KdUOrKlu52JNje2ePQe0Q=,tag:woezuFrJ4oR7JfXdo92+Iw==,type:str] - AUTHELIA_DOMAIN: ENC[AES256_GCM,data:nLkkZwSknfVmJsVidszT,iv:1S9cqc7rHiYldEiEVLTqO5zNX/VADIBxuFxGp1U8ih8=,tag:EpkltCVVDN4/l/nZvWan/w==,type:str] - QBITTORRENT_HOST: ENC[AES256_GCM,data:OZL6Z0WamN7MOlCwZCk6ktd9Unyi5ncUWrdj,iv:YUd1P6o3Dyp59Lh+YRTwf9rpcWGoFK3I96IwFCZVN6I=,tag:2pDJEqZdGLpFNscaDYRoTA==,type:str] - SONARR_HOST: ENC[AES256_GCM,data:9I2jPtwvQlDYAnEELWuPpJJIxAeFxA==,iv:H17CTaPRL/hsBcjTQNPHwrAcCe2m1vKhlon4XQwaf0o=,tag:v01S8QIh0a9wk1lct7ZsLw==,type:str] - RADARR_HOST: ENC[AES256_GCM,data:qzKq63cZcUeNLheT7w/07McfNz3duQ==,iv:/jKP9sr3SMv3jJAcMi9nBUuTNY/z4P+/3wSLwYPQvjI=,tag:E3jE9BhV8/Nqwzj8RooelA==,type:str] - MEDIA_NFS_PATH: ENC[AES256_GCM,data:jhl2aNhGVo2c9iSvEic=,iv:n2HQFKKpY07z7qNH2pENqhplMI712be/PVtLFAQzq+s=,tag:e6wUZ756DI+KN9mept1lLg==,type:str] - IMMICH_HOST: ENC[AES256_GCM,data:ZwNp4uIxaO+/53vxfy+1afRrMulXtw==,iv:FgU8lcqUi2PE1qinQ4oG7sm5hi0cVWHkBJRhGQkMivk=,tag:1YOpVOVzWBjFFN2QY3fTbw==,type:str] - IMMICH_UPLOAD_NFS_PATH: ENC[AES256_GCM,data:TewJWSY7OEHcUw2Q35Nk,iv:iVTIF/+bYW21hRmndStt57Z3H2EGZ2tf89xjLb/VZh4=,tag:hnaUsq3s3z8SLgwtYv5DIw==,type:str] - JELLYFIN_HOST: ENC[AES256_GCM,data:+k0dCgZbjVs+GcnIeGhNYX8AOO/Sm3wL,iv:u1Q8mFwKPNiYcS3c5K5W0/LCLIbB57T8Ee8bXf9NiRs=,tag:qJjxixgdHwTbU5Z8PFseQg==,type:str] - JELLYFIN_INTERNAL_HOST: ENC[AES256_GCM,data:yFCr78OQO984GoIWt77Fx5sriuI6,iv:LamCoNH08cofP/uMV6lvd6ADHts8g774ijIRc0cjb94=,tag:BeSv1jpxp8/TTZ8ps6QMZw==,type:str] - ARCHMIRROR_HOST: ENC[AES256_GCM,data:PWKJH9XA89tXVFzhNgMEyln3Dgq8agI=,iv:5bq+qCepbepOkF+9kY52ZVzk25tVQln/W7bvldTi3Lk=,tag:YTvADkDp+zT/ifBltdjc2g==,type:str] - ARCHMIRROR_NFS_PATH: ENC[AES256_GCM,data:m60wfmMqDLcS6scjjMNS2i33iA==,iv:P0QJBZRl+/spp5yVXDVIDLhuxohxahDzLntzHULdfWs=,tag:MmJ+DSjbJizV2lJBCes+fA==,type:str] - ARCHMIRROR_MIRROR_URL: ENC[AES256_GCM,data:qUj5h0dmAgngVSYILYJzt/iNkAZdW6hsjnFuo8USxQD7pY6bp1dXBjxUIJ7R,iv:9myGjoV0HHgselUzqWRgS2CMRgSTRI45AucRCe8juSU=,tag:13+FZ28pwRdtEszllTz88A==,type:str] - PODSYNC_HOST: ENC[AES256_GCM,data:8c0DPMUs1VzMoSnDPLjQMPLQpQhgMmA=,iv:L3t2HXlTMQgVf+uDkOm+RrjgqZ+twb7keC+Q2yUxlhs=,tag:vXuE+6HrQL1kbA9jKb5QVg==,type:str] - PODSYNC_NFS_PATH: ENC[AES256_GCM,data:LnQxZHtMBS80prhYTRJshdBAumGz,iv:Pkw7kzSKhoxNpJ6pfAcEndB27qcJFSzdFKAfFDxzcEo=,tag:GIM1twzbWMRKErkcaIPq0A==,type:str] - PIHOLE_HOST: ENC[AES256_GCM,data:RCiVe6zzaeC39lzhC2tjtQuaZrfeWQ==,iv:cu/oi8+zhFVyrX4FaQK5WWtakLSgwpat6YtZXgztoLg=,tag:0IAkYF+F2UHEtt7fWKB1SA==,type:str] - PAPERLESS_HOST: ENC[AES256_GCM,data:8W+Scg+ELDcCuPAqdZu/zMgf/S5zY+Oapw==,iv:eskXvzzwDi9S7P9OBq0proa/iJ5YzC7AYhUadO8u3OE=,tag:0XVEAXXS50elwNQHJIV8hA==,type:str] - PAPERLESS_MEDIA_NFS_PATH: ENC[AES256_GCM,data:IUmyWT6FU0EN+ObrDMuf6uvu,iv:KMR/S5JO/y8NYOgltF00OTXRC3Qs4Zr7AdrWSFRjrL0=,tag:2GO0y4ZVxsCP3jLhC2Rfkw==,type:str] - PAPERLESS_CONSUME_NFS_PATH: ENC[AES256_GCM,data:FPx9as/XJGcSRJPhiXo4t3xCIoLTPHI=,iv:vKiAJosUdPV7AhICIbQ24RiAZGwV9Wt/N1Qvhyfay4c=,tag:QyiyY+eMWHc+3U8LFrMI9Q==,type:str] - PAPERLESS_DATA_NFS_PATH: ENC[AES256_GCM,data:qe/r7iDGPf6S1clRUX6HzKCsulcfvtCVOCLHvypK5sjB4CU=,iv:iV3Zk062dU/6q4QBXLz+qLnG++0CgdXZA6hVsjosZa4=,tag:FDKG+cScSYyIwwUQ5Gpv3Q==,type:str] - HOMEPAGE_HOST: ENC[AES256_GCM,data:FHYDohLODCDpLg+8GD64jWKGctA=,iv:LaPvRdSkCpYLAoowsqxUGusueC4Fd0lb/uZnzjc9nTY=,tag:phpA1L9RUdtJl10ZLazFGA==,type:str] - GROCY_HOST: ENC[AES256_GCM,data:L1Npsukfk9DjRR28mKmK+hK/bKlV,iv:SmMlHZf+B1PGgQXyTzOQYmmQiNJEttq21M6uz8P67+o=,tag:sRYgVVyb5kmmRim8REHk4Q==,type:str] - GROCY_NFS_PATH: ENC[AES256_GCM,data:gvV2CMnOecOzWtsTQN5ANeFhGE/7odETESlqaE0H6IEt,iv:299FlAZ8Yy7Wcl7kCTmNaLvKM7jXxnY/Y4C6yuwyi/M=,tag:Ckf53XNcmxOO4HmeRD+Vtg==,type:str] - BACKUP_LOCAL_HOST: ENC[AES256_GCM,data:95np+hxVjRGlxhvFVVbXm++xiHWPIyVK63E=,iv:508QwvGGBUbzOUVOBzs6h0x8FKZue5Qt3tLMuALjZn8=,tag:vZVJGE/IMGzzZatGiz/WFw==,type:str] + LUBELOGGER_HOST: ENC[AES256_GCM,data:mo4RhFZ9ToCqhLptPjTmQ/ZSLpVI9520zrc=,iv:kfzOXDSTQmSL9OIuGvwRn/iImcW6UMCtGfwt06+iQoo=,tag:xT2heEQ7xZFCrDTgQiEm2Q==,type:str] + LUBELOGGER_DATA_NFS_PATH: ENC[AES256_GCM,data:qHdWlXxFEpiJ8JQUcL4K7oqTM5bO29KUNXUG1LI9M1pSYyuP,iv:eRtUjUXe2k1m/hMaj4vUISAHxLKllH9hvz6kJJbRKfA=,tag:0rQ53dRA3qOxViB3IpWvfg==,type:str] + AUTHELIA_DOMAIN: ENC[AES256_GCM,data:j3Ly+ice3WnD8Bsp4HYY,iv:hTxKhvXwg/fMWTPuj/fXQIbM0Hg8pS9nIP0dY8e3rRg=,tag:sCh+1/nEj0FcJE+NQvbr6w==,type:str] + QBITTORRENT_HOST: ENC[AES256_GCM,data:TMTdrznfaA46SiExvQx1ZzgkANLw6MA8MGLX,iv:1AxA9vEwLh8bthKEptzzbKfRAZDB1yvQ0a+HBLxKUmI=,tag:xVITE1MfFmV76TwQ9/rRuQ==,type:str] + SONARR_HOST: ENC[AES256_GCM,data:Q9OEDs7He/H1HayAOXSLrU7wvs8gQg==,iv:1dHreVGSc3zNPoWJjnvhgbUX8JxcEIF/JFL7PMIxlrs=,tag:/xDdrIMTsPmxZ39BY1Pb6w==,type:str] + RADARR_HOST: ENC[AES256_GCM,data:Iv3321zxPNtqtH6cz7hb0R74wMsYCw==,iv:88LqT+jf5qAF02kD0+ovNOLWak5YYNyWrWZksdjZ2HI=,tag:zoMJlpWJVh6l7oJH3I99HQ==,type:str] + MEDIA_NFS_PATH: ENC[AES256_GCM,data:ygNqir+aeTWDGuDSJzY=,iv:hB/EaXaYWHCFWAfrF4KRIOjsxjAWrv/PK9M5zfl4P98=,tag:/zxr9KeoQMkjrC5P5+gFMA==,type:str] + IMMICH_HOST: ENC[AES256_GCM,data:o4v0yur2+mIIpUNrX3M8dzTh6p8pLw==,iv:3TVgj/krd83qHJybk/UiXKW+K2XAMxGK+KdOGmmAhbY=,tag:z+cPhTEIPLn/UKQTD5kp3w==,type:str] + IMMICH_UPLOAD_NFS_PATH: ENC[AES256_GCM,data:ZV0eoVdFpmZcd1K80Y+l,iv:Nm40FXFxTJdpk9K+1n/qw5Hv//hOtQ1gqlPnenn/d4A=,tag:S1Oe3ekG+2HWfUXT4L07BQ==,type:str] + JELLYFIN_HOST: ENC[AES256_GCM,data:kl6DVa63VWSkJBvLAyPgdMdQWY3KQMME,iv:fZRHSmZDdzb4Q4QrQ7aWNKtoQDk6h5oiM4fNWeoVwQM=,tag:hNV90VtbFfg+pr2KpsIPbw==,type:str] + JELLYFIN_INTERNAL_HOST: ENC[AES256_GCM,data:RkkZKpdZNsDxmCCGFt5qYEwV7hL/,iv:2yjtHRXRnCxGTyOqjaVWVFH6XZKHLYfN0E0Pzz0vsmA=,tag:eS2K/bKXmby+GpzhVpkh8w==,type:str] + ARCHMIRROR_HOST: ENC[AES256_GCM,data:CGLUdXiplaG1w71pxtqMC1Yq43lM+0Y=,iv:tCVzEs+h/w4YzLdf691npWDNVCPSyky8H++sj7tsRe4=,tag:EkH5dVeZk67yFpnV2CrBEA==,type:str] + ARCHMIRROR_NFS_PATH: ENC[AES256_GCM,data:oGDI8Nl3Zf3iuMA3sNN2jqniaA==,iv:CgjUobkblU7cWI+nTV3JU7kwtOlCEDk+PDhCSBdE0mc=,tag:wFezeyn4cRrzIXDaAg7mEA==,type:str] + ARCHMIRROR_MIRROR_URL: ENC[AES256_GCM,data:DoI5nr/RSdtY4zaIfmlprAr+n2ExKA8qUKRXqhT7lOPyUZtU2ItSzY8mTIbS,iv:biT2NysvqRbpwds4MbWHIBbUmIoJ/9hUHxWOeR9AHHw=,tag:4J2yS+n4NN+hmYtSyrxVNw==,type:str] + PODSYNC_HOST: ENC[AES256_GCM,data:9JjkiVULuU4TLG7vbWoORZQsxvnAv2g=,iv:RVP7P0wlomAxbJ+856ITaQZfFOP78RJYE9HIDDqs1Gk=,tag:pJ5s8ouur7E0fYOeNkkspg==,type:str] + PODSYNC_NFS_PATH: ENC[AES256_GCM,data:eZTdkzRq6RyBls2p+c83Zs14eVFs,iv:MnZrhxJ9i9XzPgvTfmLvrq0GwATxEffXfcIX+hJ+F44=,tag:G8LEfhfNqz+JKO+m6d2JbQ==,type:str] + PIHOLE_HOST: ENC[AES256_GCM,data:Uaumycd9RVBTbG8IJtqwxz08RTZHGQ==,iv:4htbd/WBr4gY31NaocdiRUctfAEoDu5DtBgnZarxNxo=,tag:viq01wkMfYucjfh87No5Hw==,type:str] + PAPERLESS_HOST: ENC[AES256_GCM,data:tAAI/R+sg9XfLLQBXbxf+xrz1l4lIHhXpQ==,iv:VYmnOxYXftZ3GDum26bghoxxCsULpR5AOHnrGanA5YI=,tag:drVRB7ktOvmh+D87bWI66g==,type:str] + PAPERLESS_MEDIA_NFS_PATH: ENC[AES256_GCM,data:y/lRctau9ThQ5fPFdOM/HBd8,iv:qN5fIcna24uv0jHq4MNzNMDk411vgkUBk89fl2wQqig=,tag:eEMI1DVmO6ZtWUBmd8Cnug==,type:str] + PAPERLESS_CONSUME_NFS_PATH: ENC[AES256_GCM,data:bdU1NbD1gD40+xbZREdow0B40PhA1vQ=,iv:EP9z698LVr8AaOc68vEHFJ0DwsSAAWvfK+PGYN/eT24=,tag:JC9VwM5u9LKAnE6xibPJOg==,type:str] + PAPERLESS_DATA_NFS_PATH: ENC[AES256_GCM,data:uCwUZzQS6vnnZ3rKXl5UaZsRfuYSotia7pFxZTPPA+XSUzs=,iv:vSyZmSCYz2VoK8UyBFaaB4nynkm/v+9AYTaoBHk+jzg=,tag:gSAEGvxbbdeoCbTZL0VlMg==,type:str] + HOMEPAGE_HOST: ENC[AES256_GCM,data:noHdJM8h94an/Z6w5SHman+WslE=,iv:4fSqGovcPeva4lCRj7f6SYk5G7nxNYYG1Y3PaRZngbM=,tag:aM79SYGMpe81KxoXBSfHVQ==,type:str] + GROCY_HOST: ENC[AES256_GCM,data:ZiQ/OgOfqVuGSBgm4uTTlStWOmic,iv:JRA/BgFz3y8zxbYmCeZcJqU9ICMIzLEri1CHiSkdm60=,tag:0G7gFRUo++uUkSCtU+DxPQ==,type:str] + GROCY_NFS_PATH: ENC[AES256_GCM,data:XaCaZ8QsqmmnUGJlfcqFitGr5j3b2UeJJbWAaLmwgn0Y,iv:manP8bjzo1rlfIh0pFeLGI16Sxc/v5uwKwcOvk5fAJg=,tag:ucQ+MYlfuYmRobBDk69U+w==,type:str] + BACKUP_LOCAL_HOST: ENC[AES256_GCM,data:ph1AVgk0R7hYC0lwLFk0fIIGqO/Y237DGaM=,iv:vt48bzCXVtBJeCvbEJLPqY3L7TuQelZaKC90LHMw8TY=,tag:xS9aUhuUC8EfE6p4elKemg==,type:str] sops: age: - recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxS3AzeW9JdFRTTXI2WmtT - WlltTTNxWnpnUHZaVzNsZ3RtU3pyekhITW5JCnpNdUpId25XU3lHYjFxcHBMSDZR - UFh6VjlvMC9md1l3bXNuTVM0Nk9lbTAKLS0tIEFWQ0tncUw4eXFNRWVMNVJGR2NS - SFVnVnl1S05zQlVIQXJHZ29qT29JNG8K9oFAYFu2S6vzm+6wYxRV8EFw6Rc4OH3S - TiV4znizHncrYZelEYiCdCU84DIR/jz82oMBLuIM7bQhISzYMBcMUA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpUXpQVDcxWmhaMVVFKy9n + aXgyLzBrU1dUNC90VnFEbWhwNkVlUy8yaFdvCmFjeEVEeWF1UUlCV3dqT096d1Z5 + YUV6bHZ2eUNvZXZRRXkvVVZ0VTVyalkKLS0tIGdUN0dDVnlDUnYwZCs0c3NNd3ht + WDZkSzBPSWdqV3VlVE1xSE5VQ0hObXcKaSynnP7cN8VI2vUtIaexGAY7eWdQ5M8B + YIF0ijHuzUGBzdgx0oyA9SX+3LiHPGuVt3nbQk/RAUzzc4GYxoX1JQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-12T09:40:41Z" - mac: ENC[AES256_GCM,data:HhchguFiu4iHOa/Tyg4MvpECJ6aEAczdjMmtsM9qNTWS90YyYHXAq/OD0/iXV4LFMAhPFRZWE/vW+YOJuAjQmTGD7t9ADcgg/BFS0NSEq4/nKoBMEXqtATLGdX3m5eTFFeCbZZ6FI5wUvAfp6Ubwt8d7LilSg7fuTVEuivADXlU=,iv:JZayl8TrokOgYpY17J69GOP1GaFK6JmKmYoLEkuFBms=,tag:Gf6EEYZdtut+tfugYdau6Q==,type:str] + lastmodified: "2026-03-12T10:47:06Z" + mac: ENC[AES256_GCM,data:4Jeh3BpZ1eEWm5BZujXG2TBIAgVr2y6PgQvLXLhYpDvJohzL+lwbeiB0/CbW/jC5iKddivyJaA7FxgBoJK9DHMc1+r198nmiC5e38vQ+wIGgpPxBcF5CuBg1ogfudu6y5TowINYnsfUR4/6APOcan+xuHFTz4kzqmzuMtThbRSw=,iv:zwPaN6AQxklGCkkhCgvUWP4NdaO8APPou6PMxkPeyT0=,tag:YFueXynrxa4iRSGN2v1u2A==,type:str] encrypted_regex: ^(data|stringData|email)$ version: 3.12.1