# Backup-Ordnerstruktur — dmz-backup + Synology Pull

Stand: 2026-06-19

## Zielbild

- `dmz-backup` (`192.168.20.90`) ist der DMZ-Staging-Host.
- K3s/DMZ-Cluster darf Backups nach `dmz-backup` pushen.
- Synology/DiskStation pullt von `dmz-backup` und bleibt Backup-Master.
- Direkte Schreibrechte aus der DMZ auf Synology werden vermieden.

## Empfehlung

Ja: diskstation-bot soll die Struktur grundsaetzlich nach Platform/Tenants uebernehmen.

Nicht nur nach Kubernetes-Namespace sortieren, weil aktuelle Namespaces historisch gewachsen sind (`hf-*`, `pidoka-hf-*`, `homarr`, `zammad`). Besser ist:

1. fachliche Grenze: `platform` oder `tenants/<tenant>`
2. Umgebung: `prod`, `stage`, `dev`
3. Anwendung/Komponente
4. Backup-Art: `db-dumps`, `files`, `volume-backups`, `manifests`, `metadata`, `restore-tests`

## Vorgeschlagener Root

Auf `dmz-backup`:

```text
/srv/dmz-backup/k3s-dmz/
```

Auf Synology als Pull-Ziel sinngemaess:

```text
K3S_DMZ_Backups/
```

## Ordnerstruktur

```text
k3s-dmz/
  README.md
  _incoming/
    quarantine/
    incomplete/
  _indexes/
    latest.json
    backup-catalog.jsonl
    checksums/
  _restore-staging/
    platform/
    tenants/

  platform/
    argocd/
      prod/
        manifests/
        app-exports/
        restore-tests/
    infisical/
      prod/
        db-dumps/
        app-exports/
        restore-tests/
    external-secrets/
      prod/
        manifests/
        crd-inventory/
    longhorn/
      prod/
        volume-backups/
        metadata/
        restore-tests/
    nginx-proxy-manager/
      prod/
        database/
        letsencrypt/
        config/
        restore-tests/
    cluster/
      prod/
        manifests/
        inventory/
        events/
        node-metadata/

  tenants/
    pidoka/
      prod/
        n8n/
          db-dumps/
          files/
          manifests/
          restore-tests/
        matomo/
          db-dumps/
          files/
          manifests/
          restore-tests/
        mautic/
          db-dumps/
          files/
          redis/
          manifests/
          restore-tests/
        suitecrm/
          db-dumps/
          files/
          manifests/
          restore-tests/
        zammad/
          db-dumps/
          files/
          manifests/
          restore-tests/
        homarr/
          db-dumps/
          files/
          manifests/
          restore-tests/

    cattaro/
      stage/
        guestbook/
          manifests/
          restore-tests/
      prod/
        _reserved/

  legacy/
    hf-matomo/
      prod/
        db-dumps/
        files/
        manifests/
        restore-tests/
    default-my-release/
      prod/
        db-dumps/
        manifests/
        restore-tests/
    keycloak/
      prod/
        db-dumps/
        manifests/
        restore-tests/
```

## Dateinamensschema

Empfohlen:

```text
<UTC timestamp>__<cluster>__<tenant-or-platform>__<app>__<kind>__<scope>.<ext>
```

Beispiele:

```text
20260619T193000Z__dmz-k3s__pidoka__matomo__db-dump__mariadb.sql.gz
20260619T193000Z__dmz-k3s__pidoka__zammad__files__uploads.tar.zst
20260619T193000Z__dmz-k3s__platform__argocd__manifests__apps.yaml.gz
20260619T193000Z__dmz-k3s__platform__longhorn__metadata__volumes.json.gz
```

Zu jedem Backup gehoert eine kleine Metadatendatei:

```text
<backup-file>.meta.json
<backup-file>.sha256
```

## Minimale Metadaten

```json
{
  "created_at_utc": "2026-06-19T19:30:00Z",
  "cluster": "dmz-k3s",
  "source_host": "192.168.20.40",
  "backup_staging_host": "dmz-backup",
  "backup_staging_ip": "192.168.20.90",
  "category": "tenant",
  "tenant": "pidoka",
  "environment": "prod",
  "app": "matomo",
  "namespace": "pidoka-hf-matomo",
  "kind": "db-dump",
  "contains_secrets": false,
  "encryption": "tbd",
  "retention_class": "prod-standard",
  "restore_test_required": true
}
```

## Retention-Klassen

Vorschlag fuer diskstation-bot:

- `prod-critical`: taeglich 30 Tage, woechentlich 12 Wochen, monatlich 12 Monate
- `prod-standard`: taeglich 14 Tage, woechentlich 8 Wochen, monatlich 6 Monate
- `platform-critical`: taeglich 30 Tage, woechentlich 12 Wochen, monatlich 12 Monate
- `legacy-cleanup`: taeglich 7 Tage, woechentlich 4 Wochen, danach nur falls explizit markiert
- `pre-change`: mindestens 30 Tage oder bis Change/Restore-Test abgeschlossen ist
- `restore-test-artifacts`: 14 Tage, sofern kein Incident-Beleg

## Security-Leitlinien

- Cluster bekommt nur Schreibrechte auf definierte Zielpfade auf `dmz-backup`.
- Synology bekommt Pull-Rechte von `dmz-backup`, idealerweise read-only.
- Kein breit nutzbarer Synology-Key im Cluster.
- Backups mit Secret-/Credential-Inhalt markieren und bevorzugt vor Ablage verschluesseln.
- Synology-Pull initial ohne destruktives `--delete`.
- Nach erfolgreichem Pull zur DiskStation und erfolgreichem SHA256-Verify auf der DiskStation wird das konkrete Quellartefakt plus `.sha256` auf `dmz-backup` geloescht. Keine Wildcards. Loeschungen sind destruktiv und brauchen fuer den jeweiligen Lauf explizites OK bzw. spaeter eine freigegebene Automatisierungsregel.
- Restore-Test ist Pflicht: Backup ohne getesteten Restore gilt nicht als belastbar.

## Restore-Staging-Konzept — Stand 2026-06-21

Restore-Staging ist Arbeitsflaeche, nicht Langzeitarchiv. Die autoritative Backup-Kopie liegt auf der DiskStation.

Auf DiskStation:

```text
/volume1/KI_Agenten/backups/k3s-dmz/_restore-staging/
  <tenant>/
    <env>/
      <app>/
        <restore-id>/
```

Auf `dmz-backup` analog:

```text
/srv/dmz-backup/k3s-dmz/_restore-staging/
  <tenant>/
    <env>/
      <app>/
        <restore-id>/
```

Fuer Homarr wurde der Pfad im Pilot verwendet:

```text
/srv/dmz-backup/k3s-dmz/_restore-staging/pidoka/prod/homarr/20260621T1733Z-homarr-pilot-restore/
```

Trigger:

- kube-bot startet Restore-Prozesse, weil kube-bot den K3s-/Workload-Kontext kennt.
- diskstation-bot liefert verfuegbare Versionen von der DiskStation und legt das gewuenschte Artefakt nach `dmz-backup` ins Restore-Staging.
- kube-bot uebernimmt ab `dmz-backup`: Verify, Decrypt, Manifest-/Payload-Pruefung und spaeter isolierter Restore.
- Produktive Restore-Schritte bleiben zustimmungspflichtig.

Cleanup:

- Restore-Staging darf nach erfolgreichem Test/Restore geloescht werden.
- Restore-Staging wird nicht als zweite dauerhafte Backup-Struktur genutzt.

## Mapping aktueller DMZ-Workloads

- Platform:
  - `platform-infisical` -> `platform/infisical/prod/`
  - `argocd` / IT15-ArgoCD Exporte -> `platform/argocd/prod/`
  - `external-secrets` -> `platform/external-secrets/prod/`
  - Longhorn -> `platform/longhorn/prod/`
  - Nginx Proxy Manager auf `192.168.20.20` -> `platform/nginx-proxy-manager/prod/`
- Tenant `pidoka`:
  - `hf-n8n` -> `tenants/pidoka/prod/n8n/`
  - `pidoka-hf-matomo` -> `tenants/pidoka/prod/matomo/`
  - `hf-mautic` -> `tenants/pidoka/prod/mautic/`
  - `hf-suitecrm` -> `tenants/pidoka/prod/suitecrm/`
  - `zammad` -> `tenants/pidoka/prod/zammad/`
  - `homarr` -> `tenants/pidoka/prod/homarr/`
- Legacy:
  - alter Namespace `hf-matomo` -> `legacy/hf-matomo/prod/`
  - default `my-release` -> `legacy/default-my-release/prod/`
  - alter `keycloak` -> je nach Entscheidung `legacy/keycloak/prod/` oder spaeter `platform/keycloak/prod/`

## Offene Punkte fuer diskstation-bot

1. Finalen Synology Share-Namen festlegen.
2. Pull-Protokoll festlegen: SSH/rsync bevorzugt; alternativ SFTP.
3. Retention/Snapshot/Immutability pro Retention-Klasse abbilden.
4. Quota fuer `dmz-backup` und Synology-Ziel definieren.
5. Verschluesselung entscheiden: dateibasiert vor Ablage oder Synology-seitig.
6. Ersten Restore-Testpfad definieren: Synology -> `dmz-backup` -> isolierter Restore im Cluster.
