Update 2026-05-04 — Deployment-Status synchronisiert
RZ-DEPLOYED (2026-05-01 Phase-0..7): vm-rz-edge-01, vm-rz-svc-prod-01, vm-rz-db-01, vm-rz-reg-01, vm-rz-app-prod-01, vm-rz-app-stage-01.
HM-DEPLOYED (2026-05-02..03): vm-hm-edge-01, vm-hm-svc-prod-01, vm-hm-app-prod-01, vm-hm-db-01, vm-hm-backup-01.
HM-IN-MIGRATION: vm-hm-dc-01 (Proxmox-Import blockt auf ESXi-Snapshot-Reference).§4.1 Korrektur: Die Notiz "
10.200.0.200= Authentik LDAP-Outpost-IP" ist obsolet — Outpost ist seit 2026-05-02 auf10.200.0.101(vm-rz-svc-prod-01:389/636).Cross-Link zur per-VLAN DNS-Matrix:
/policies/ip-allocation-hm(re-locked 2026-05-03).
Status: Draft v2 (post-review) · 2026-05-01
Author: Claude (Senior Infra Eng. role) · review-corrections von Alex eingearbeitet
Scope: RZ (Hetzner ESXi) + Home (Proxmox VE-IO-01).
Single source of truth für die Konsolidierung. Day-to-day-Changelog lebt in
/migration/linux-vm-sweep-2026-04-30und Folge-Seiten.
Wenn etwas dieser Seite widerspricht ist es entweder (a) ein Change-Request, der hier reingehört, oder (b) ein temporärer Workaround.
:latest in Prod. Renovate öffnet MRs, Pipeline deployed.blackreset.internal (Firewalls, interne DNS, Mgmt-FQDNs). Einzige Ausnahme: Windows-Welt bleibt auf xio.bio bis das AD selbst weg kann. Public-User-facing Apps laufen weiterhin unter *.blackreset.com.VM-{SITE}-{ROLE}[-TIER]-{NN}
| Token | Werte |
|---|---|
SITE |
RZ (Hetzner), HM (Home / Lörrach), LG (Lager-NAS-Site, später) |
ROLE |
EDGE APP SVC DB MAIL MEDIA GAME DC BACKUP REG BUILD FW |
TIER |
PROD STAGE TEST (nur bei APP/SVC nötig) |
NN |
zweistellig, fortlaufend pro SITE+ROLE+TIER |
Beispiele: VM-RZ-DB-01, VM-RZ-APP-PROD-01, VM-HM-SVC-PROD-02, VM-HM-DC-01, VM-RZ-MAIL-01, VM-RZ-REG-01.
Container-Namen (innerhalb einer VM): {role}-{service} ohne Site-Token. Beispiele: svc-nextcloud, db-postgres, edge-traefik, app-radio.
DNS-Konvention:
cloud.blackreset.com, git.blackreset.com, reg.git.blackreset.com, radio.blackreset.com …{vmname}.{site}.blackreset.internal (z.B. vm-rz-db-01.rz.blackreset.internal) — pfSense-Resolver, nicht öffentlich.*.app.blackreset.com → CNAME auf EDGE, Traefik routet anhand Host-Header → kein DNS-Touch beim Deploy einer neuen App.Übergang weich: Neue VMs ab heute neues Schema. Bestehende
VM-SL-0Xwerden erst beim Decom umbenannt — kein Big-Bang-Rename.
*.blackreset.com → A-Record auf EDGE-IP. Eine neue App im Pipeline-Deploy braucht keinen DNS-Change: das Compose des neuen Stacks setzt Host(\mynewapp.blackreset.com`)` als Traefik-Router-Label, EDGE-Traefik discovert das via Docker-API über VPN-Sock (oder via konfig-file-Provider, der per Pipeline aktualisiert wird) und routet sofort. DNS bleibt ruhig.*.blackreset.com-Public-Ports (80/443) gehen ausschließlich an EDGE-IPs (RZ + HM). Nur Mail-Ports (25/465/587/993) gehen direkt von der Cloud-Firewall an die Mail-IP der MAIL-VM. Mailcow-Web-UI (SOGo, Admin-UI) läuft trotzdem über EDGE → SOGo-Container.| VM | Rolle | Public Exposure |
|---|---|---|
| VM-RZ-EDGE-01 | Traefik (alle :80/:443), CrowdSec, fail2ban, Authentik-Outpost-LDAP-rz, Telegraf-Relay | static-1 (Web) |
| VM-RZ-MAIL-01 | Mailcow (Compose, Host-Networking), interne MariaDB | static-mail (SMTP/IMAP/443) |
| VM-RZ-SVC-PROD-01 | NC, GitLab, GitLab Container Registry (reg.git.blackreset.com), Authentik, BookStack-RO-Archiv, Wiki.js, Vaultwarden, UptimeKuma-Slave, Loki, Grafana, Prometheus |
via EDGE |
| VM-RZ-SVC-TEST-01 | Test-/Spielwiese-Services | via EDGE |
| VM-RZ-APP-PROD-01 | self-built Apps (Radio + andere Compose-Stacks) + GitLab-Runner (Docker executor) | via EDGE |
| VM-RZ-APP-STAGE-01 | Staging der self-built Apps + GitLab-Runner | via EDGE |
| VM-RZ-DB-01 | Postgres + MariaDB Container (RZ-lokal, eigenständig, keine Repl) | intern only |
| VM-RZ-REG-01 | Harbor: Proxy-Cache für docker.io / ghcr.io / quay.io + Vulnerability-Scan (Trivy) | intern only (Pull-Cache) |
MON wurde zusammengelegt mit SVC-PROD-01. Eigene MON-VM erst wenn SVC-Last es erzwingt.
Vaultwarden lebt im RZ (immer-erreichbar-Anforderung). HM-Outage darf Password-Manager nicht killen.
GitLab Container Registry bleibt GitLab-built-in unterreg.git.blackreset.com(Daten in GitLab-Volume). Harbor auf REG-01 ist ausschließlich Proxy-Cache + Scanner für Upstream-Images, nicht Ziel von CI-Pushes. Beide Registries sind explizit getrennt.
| Bestand | Zielzustand |
|---|---|
| VM-SL-01 | Bereits decomissioned. Nach 30-Tage-Karenz löschen. |
| VM-SL-02 (Mailcow) | → Daten auf VM-RZ-MAIL-01 migrieren (parallel + IP-Switch). Decom. |
| VM-SL-03 (NC native) | → NC als Container auf VM-RZ-SVC-PROD-01. Postgres → VM-RZ-DB-01. Decom. |
| VM-SL-04 (GitLab) | → GitLab Docker official auf VM-RZ-SVC-PROD-01. Postgres → VM-RZ-DB-01. Registry-Volume mitnehmen. Decom. |
| VM-SL-05 | Audit done (/inventory/vm-sl-audit-2026-05-01): CUPS + script-server + Docker-Reste, kaum Last. CUPS → VM-HM-SVC-PROD-01 (Phase 13), Rest evaluieren + decom. |
| VM-SL-06 | Audit done: AzuraCast Multi-Station (~25 Stationen, hybrid native+Docker). Migration → VM-RZ-APP-PROD-01 (Phase 8) per azuracast backup-Bundle. |
| VM-SL-09 | Audit done: Pterodactyl Panel + Wings (Game-Manager). Migration → VM-HM-GAME-01 als Pelican Panel (Phase 14). Disk fast voll (86 %), 200 GB sdb unmounted. |
| VM-DB-01 | → Postgres + MariaDB-Daten umziehen auf VM-RZ-DB-01. Decom. |
| VM-DB-02 (MSSQL) | → §6 (Audit erst, dann pgloader oder pgdump-Archiv). Decom. |
| VM-DC-01 | → Migration nach Home als VM-HM-DC-01. |
| Game-VMs | Out of scope; siehe §3 (Game zieht nach Home). |
| VM | Rolle | Notes |
|---|---|---|
| VM-TS-12 | Alex' Main / Claude-Host | Unverändert (UAC, freie FW-Regeln) |
| VM-HM-DC-01 | AD DC (Windows Server, 1:1-VM-Migration aus RZ, kein OS-Wechsel) | nur Windows-Pflege, Apps reden nicht damit |
| VM-HM-EDGE-01 | Traefik, CrowdSec, Authentik-Outpost-LDAP-hm, dyn-DNS-Updater | Hetzner-DNS-API für DynDNS |
| VM-HM-SVC-PROD-01 | UptimeKuma (Hauptinstanz), Homepage-Dashboard, CUPS-Container, Unifi-Network-Controller, weitere Home-Services (Detail per VM-Decom-Audit) | „Schweizer Taschenmesser" |
| VM-HM-SVC-PROD-02 | Plex, Tautulli, Immich, Tdarr (Movies+Series only, niemals Photos/Immich) — media-mapped services | NAS-Mount, ehemals VM-HM-MEDIA-01 (renamed 2026-05-01) |
| VM-HM-APP-PROD-01 | Self-built Compose-Stacks prod + GitLab-Runner heavy (Docker executor, tag home-heavy) |
i9-CPU; vereint App-VM + Runner (BUILD-01 entfallen) |
| VM-HM-APP-STAGE-01 | Self-built Compose-Stacks stage + GitLab-Runner stage (Docker executor, tag home-stage) |
Staging-Umgebung für Pre-Prod-Tests |
| VM-HM-DB-01 | Postgres + MariaDB Container (Home-lokal, eigenständig, keine Repl mit RZ) | |
| VM-HM-BACKUP-01 | „Databasement" — Restic/Borg, MinIO. Bindet Storage direkt von außen ein (NAS-NFS/SMB, externe Disks per virtio-block) — keine fette virtuelle Disk im VM-Image. | NAS + Replikation → Lager-NAS |
| VM-HM-GAME-01 | Game-Server (Pelican Panel) — max. 4 gleichzeitige Player, selten | später (Phase 14) |
| VM-HM-HA | Home Assistant | Unverändert |
| VM-SW-03 | Drucker-Server (Windows) | Decom geplant — CUPS auf SVC-01 (siehe §3.3) |
Update 2026-05-01 (Alex): VM-HM-BUILD-01 entfällt; Build-Runner-Funktion fusioniert mit APP-VMs in PROD+STAGE-Split (analog VM-RZ-APP-PROD-01/STAGE-01). VM-HM-MEDIA-01 → VM-HM-SVC-PROD-02 umbenannt — konsistenter
SVC-Namensraum, aber reserviert für media-mapped services (Plex/Tdarr/Immich/Tautulli mit NAS-Mount).
Kein WireGuard-Container in Home. Site-to-Site läuft auf den Firewalls (pfSense ↔ pfSense), VPN-Roadwarrior ebenfalls auf der Firewall.
VM-HM-DC-01 = 1:1-Move: wir ziehen die existierende Windows-DC-VM komplett um, kein OS-Wechsel auf Samba.
| Service | VM | Engine | Domain / Port | Auth |
|---|---|---|---|---|
| UptimeKuma (Haupt) | VM-HM-SVC-PROD-01 | Container | uptime.blackreset.com |
OIDC |
| Homepage-Dashboard | VM-HM-SVC-PROD-01 | Container | home.blackreset.com |
OIDC |
| CUPS (Drucker) | VM-HM-SVC-PROD-01 | Container | LAN-only, IPP | local |
| Unifi-Network-Controller | VM-HM-SVC-PROD-01 | Container | unifi.blackreset.internal:8443 |
local |
| Plex (Media) | VM-HM-SVC-PROD-02 | Container | plex.blackreset.com |
Plex |
| Tautulli | VM-HM-SVC-PROD-02 | Container | tautulli.blackreset.com |
OIDC |
| Immich | VM-HM-SVC-PROD-02 | Container | photos.blackreset.com |
OIDC |
| Tdarr (Movies/Series only) | VM-HM-SVC-PROD-02 | Container | LAN UI | local |
| Home Assistant | VM-HM-HA | Native | ha.blackreset.com |
OIDC |
| Self-built Apps | VM-HM-APP-PROD-01 | Compose | *.blackreset.com via EDGE |
OIDC |
Restliche Home-Services (z.B. eigene Custom-Skripte, kleine Tools) werden im Per-VM-Decom-Audit (Phase 9 + Phase 13/15) erfasst und beim Umzug der jeweiligen Bestands-VM auf SVC-01 oder APP-01 verschoben.
VM-SW-03 ablösen — ja. Drucker-Funktion = CUPS-Container auf VM-HM-SVC-PROD-01. Voraussetzung Treiber-Verify: Brother MFA-PPDs als CUPS-Driver verfügbar (je nach genauem Modell — IPs in pfSense, Modell aus Webinterface auslesen).
Lancache weg — bestätigt. Decom nach Backup der Cache-Stats (falls historisch interessant).
Paperless-ngx — entfällt. Steht nicht mehr auf der Roadmap.
DC nach Home (locked): DC zieht ins Home, ABER niemals Auth-Quelle für Apps. Apps reden ausschließlich mit Authentik im RZ. AD und Authentik sind NICHT disconnected — Authentik zieht via existierender LDAP-Source
ldap-xio-bioeinseitig User+Gruppen aus AD nach Authentik (read-only); umgekehrt nichts. Wenn S2S-VPN ausfällt, sind App-Logins (NC, GitLab, Wiki, Mailcow-SOGo) trotzdem unbeeinträchtigt — sie sprechen mit Authentik im RZ, Authentik braucht den DC nicht zur Laufzeit, nur zum periodischen Sync-Lauf.Game-Server nach Home — bestätigt. Max ~4 gleichzeitige Player, selten. Bandbreite reicht.
Dashboard: Heimdall ist tot, Homepage kommt rein (Widgets für Plex/PiHole/Kuma/GitLab/Authentik, OIDC, YAML-in-Git).
GitLab-Runner Home (VM-HM-APP-PROD-01): Stromkosten Home günstiger, CPU stärker (i9 vs Xeon). RZ-Runner für schnelle Jobs, Home-Runner für
home-heavyTags.
| VLAN | Interface | Subnet | Zweck | Beispiel-VMs |
|---|---|---|---|---|
| 100 | (intern) | 10.100.0.0/24 |
SERVER (DB) | VM-RZ-DB-01, VM-RZ-REG-01 |
| 200 | vmx1 | 10.200.0.0/24 |
DMZA — SVC | VM-RZ-SVC-PROD-01, VM-RZ-SVC-TEST-01, VM-RZ-APP-PROD-01, VM-RZ-APP-STAGE-01, VM-RZ-MAIL-01 |
| 210 | vmx1 | 10.210.0.0/24 |
DMZB — Game | Game-VMs (RZ-Restbestand bis Phase 14) |
| 300 | vmx1 | 10.250.0.1/24 |
EDGE (war LAB) | VM-RZ-EDGE-01 |
LAB → EDGE Rebuild: das alte LAB-Netz war leer und darf umgebaut werden. VLAN 300 /
10.250.0.0/24ist der neue EDGE-Anker; nur die EDGE-VM hängt dort.
10.200.0.200ist heute die Authentik-LDAP-Outpost-IP (vm-sl-00) — das bleibt während der Migration; nach Cutover läuft der Outpost als Container auf VM-RZ-EDGE-01 oder VM-RZ-SVC-PROD-01.
Per VLAN ein klares Pattern. Last-Oktett = 100 + (10 × role-block) + NN. So bleibt jede IP ihrem Role+NN sofort zuordenbar.
DMZA (VLAN 200, 10.200.0.0/24) — IPs 100-149 neu vergeben:
| Block | Role | IP-Range | NN-Belegung |
|---|---|---|---|
| 0 | SVC | .100-.109 |
.101 = VM-RZ-SVC-PROD-01, .102 = VM-RZ-SVC-TEST-01 |
| 1 | APP | .110-.119 |
.111 = VM-RZ-APP-PROD-01, .112 = VM-RZ-APP-STAGE-01 |
| 2 | .120-.129 |
.121 = VM-RZ-MAIL-01 |
|
| 3 | (Reserve / Aux) | .130-.139 |
future MON/FW-aux/etc. |
| 4 | spare | .140-.149 |
open |
Bestehende statische Belegungen bleiben:
.1 pfSense Gateway.50-.99 DHCP-Range (für Ephemerals / Test-VMs).151/.152 VM_SW_01/02.200-.209 VM_SL_00..09 (Decom-Pfad)EDGE (VLAN 300, 10.250.0.0/24) — gleiches Pattern:
.101 = VM-RZ-EDGE-01SERVER (VLAN 100, 10.100.0.0/24) — DB / REG VMs.
Role-Block-Shift weil Block 0 schon Legacy-besetzt ist:
| Block | Role | IP | Zustand |
|---|---|---|---|
| 0 | (Legacy era — locked) | .101 |
VM_DB_01 — Decom Phase 9 |
| 0 | (Legacy era — locked) | .102 |
VM_DB_02 (MSSQL) — Decom Phase 4 + 9 |
| 1 | DB neu | .111 |
VM-RZ-DB-01 |
| 2 | REG | .121 |
VM-RZ-REG-01 |
Weiteres im SERVER-Subnet:
.10 = VM_DC_01 (zieht nach Home als VM-HM-DC-01 in Phase 11).250 = ESXi00 (Hypervisor)Home SERVER (VLAN 1000, 10.100.100.0/24) — gleiches Pattern für VM-HM-*:
.101 = Proxmox-Home host (baremetal, NOT in DHCP — was VM-HM-SVC-PROD-01 in original plan, conflict found 2026-05-02).102 = VM-HM-SVC-PROD-01 (UptimeKuma + Homepage + CUPS + Unifi).103 = VM-HM-SVC-PROD-02 (media-mapped services, ex-MEDIA-01).104 = VM-HM-APP-PROD-01 (+ GitLab-Runner heavy).105 = VM-HM-APP-STAGE-01 (+ GitLab-Runner stage + builds).111 = VM-HM-DB-01.131 = VM-HM-BACKUP-01.142 = VM-HM-DC-01 (was .141 — Unifi UAP conflict, moved 2026-05-02).151 = VM-HM-GAME-01.103 = VM-HM-BUILD-01.103 is now VM-HM-SVC-PROD-02 (media-mapped, ex-MEDIA-01).Home EDGE (VLAN 1500, 10.150.100.0/24):
.101 = VM-HM-EDGE-01Allokations-Methode: pro VM eine DHCP-Static-Reservation auf der jeweiligen pfSense (anhand MAC), nicht statisch in der VM-Konfig. Single-source-of-truth = pfSense; Re-Install der VM behält IP solange MAC gleich. Reservations werden via pfSense RESTAPI automatisiert (Teil von tools/onboard-vm.sh).
Firewall-Regeln (Default-Deny pro VLAN):
apt (über pfSense-Forwarder), sonst nichts.| VLAN | Interface | Subnet | Zweck | VMs |
|---|---|---|---|---|
| 1000 | vtnet0 | 10.100.100.0/24 |
SERVER (alles Linux + DC + HA) | alle VM-HM-*, VM-HA, VM-TS-12 (Server-Side) |
| 1500 | vtnet0 | 10.150.100.0/24 |
EDGE (war LAB) | VM-HM-EDGE-01 |
| — | — | unverändert | HA, Clients, IoT etc. | Home-Restnetze bleiben so wie heute |
HA-VLAN bleibt. IoT-, Client-, Gäste-VLANs bleiben. LAB-Netz ist frei zum Umbau und wird zu VLAN1500/EDGE.
*.blackreset.com → Traefik)./network/hetzner-ips.| Engine | Wo? | Welche Apps |
|---|---|---|
| Postgres | VM-RZ-DB-01 + VM-HM-DB-01 (eigenständig) | Nextcloud, GitLab, Authentik, Vaultwarden, Immich, Wiki.js (Migration v.10), self-built Apps |
| MariaDB | VM-RZ-DB-01 + VM-HM-DB-01 (eigenständig) | Mailcow (intern, nicht extrahiert), Bookstack-Legacy-Read-Only, Unifi-Controller |
| Redis | je in App-VM (Sidecar) | Cache only |
| MSSQL | weg | siehe §6 |
Architektur:
/var/lib/postgresql/data auf eigenem LVM-Volume; Snapshots vor Schema-Migrations.db.rz.blackreset.internal bzw. db.hm.blackreset.internal (Direct TCP, kein Traefik).Wunsch: „Wildcard-DNS, damit man in CI/CD schnell stagen kann."
Zwei Wildcards:
*.blackreset.com → A → EDGE-IP. Traefik routet an Service.*.db.rz.blackreset.internal → A → VM-RZ-DB-01. App-DSN: host=mynewproject.db.rz.blackreset.internal. Postgres-DB-Name + User per Pipeline-Job angelegt.mail.blackreset.com ein expliziter Record außerhalb des Wildcards ist.| Schritt | Was |
|---|---|
| 1 | Audit: welche DBs auf MSSQL, welche Apps, welche Datenmenge. Skript Phase 0. |
| 2 | Pro DB: Schema-Export (mssql-scripter) — Review der Typen. |
| 3 | pgloader mssql://… postgresql://… falls weiter genutzt — sonst direkt pgdump-Archiv. |
| 4 | App-Connect-String in Stage umstellen, Smoke-Test, Daten-Diff (row-counts, hash-of-table). |
| 5 | Cutover: Maintenance-Fenster, finale Replikation, App auf Postgres, MSSQL-Read-Only. |
| 6 | 30 Tage RO-Karenz, dann Decom DB-02. |
Databasement-Hinweis: VM-HM-BACKUP-01 hat KEINE direkte Konnektivität zu MSSQL. Backups vor Migration laufen lokal auf VM-DB-02 (
sqlcmd BACKUP DATABASE) und werden anschließend per Restic ins Databasement geschoben — nicht direkt remote. Steht so auch im Backup-Plan §9.
NC und GitLab sind 2026-04-30/05-01 erfolgreich an Authentik angebunden worden. Locked-State liegt in /migration/nc-authentik-2026, /migration/gitlab-authentik-2026, /migration/authentik-ldap-outpost-2026 und der Policy-Seite /access/identity-policy.
Kern-Learnings (verbindlich für alle weiteren App-Anbindungen):
sub/uid im selben User-Datensatz.user_id-Spalte updaten, alles andere lassen. Sonst sind verschlüsselte Daten verloren.default-authentication-flow sein, nicht default-provider-authorization-implicit-consent (sonst FlowNonApplicableException → Bind-Fehler).OIDC-Property-Mappings (Standard für alle künftigen Apps):
sub_mode = user_uuid (Authentik-Provider-Setting).uid_field = sub (oder Equivalent).openid profile email groups offline_access.default-authentication-login mit session_duration=days=30.Group-Mapping:
grp-{app}-user, grp-{app}-admin ausschließlich in Authentik gepflegt.Audit-Skript
tools/audit-ad-vs-authentik.py(CSV-Diff) — vor jeder weiteren App-Anbindung neu laufen lassen.
Base: Debian 13 (Trixie) — minimal Netinst. Cloud-Init + Ansible-Playbook macht aus „leerer VM" einen „Standard-Host".
Was im Standard ist:
unattended-upgrades (security only, daily).needrestart + Cron 03:30 wenn Kernel-Update.node_exporter (Prometheus → SVC-PROD-01).promtail → Loki auf SVC-PROD-01.sshd only key-auth, PermitRootLogin no, Fail2Ban.blackreset mit sudo-NOPASSWD nur für docker compose./opt/{service}/{compose.yml,.env,data/}.m@blackreset.com (System-Mailtarget, Cron-Mail, Renovate-Notifications, Mailcow-Postmaster). server@blackreset.com als to-inform/CC für Ops-Reports.Update-Strategie:
| Tier | Update-Modus |
|---|---|
| Prod-kritisch | Renovate-MR → Pipeline deployt nach Approval |
| Prod-statisch | Renovate auto-merge minor/patch nach 7 Tagen + CI-grün |
| Test/Spielwiese | Watchtower (Opt-in pro Container via Label) |
Standard-Compose-Skeleton (geteilt im internen Repo infra/compose-template):
services:
app:
image: registry.blackreset.com/proxy/upstream/app:${VERSION}
restart: unless-stopped
security_opt: [no-new-privileges:true]
cap_drop: [ALL]
read_only: true
tmpfs: [/tmp]
networks: [edge, data]
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.blackreset.com`)
- traefik.http.routers.app.tls.certresolver=le
- com.centurylinklabs.watchtower.enable=false
networks:
edge: { external: true, name: edge }
data: { external: true, name: data }
Kurz: Nein. Ansible ist agentless, läuft per SSH. Du brauchst nur eine Control-Node-Workstation (z.B. VM-TS-12 oder Claude-Host) mit ansible-core + Python. Playbooks liegen im Git-Repo infra/baseline. CI führt Trockenläufe (ansible-lint, --check --diff) gegen Stage-Inventory aus, Apply auf Prod manuell oder per Pipeline.
Optional später: SemaphoreUI oder AWX als Web-UI um Playbook-Runs für nicht-CLI-Auslöser bequem zu starten — kann in einem Container auf VM-RZ-SVC-PROD-01 mit ~512 MB RAM laufen, kein eigener Server. Erst wenn du oder Jonas Ansible regelmäßig ohne Terminal nutzen wollt.
| Layer | Methode | Retention | Wohin |
|---|---|---|---|
| L1 | PBS / Proxmox-Backup für VM-Images (täglich 04:00) | 7d/4w/12m | NAS, dann Lager-NAS |
| L2 | Postgres WAL-archiving + nightly base; MariaDB nightly mysqldump | 30d | MinIO auf VM-HM-BACKUP-01 |
| L3 | App-Level: NC occ files:scan + files-rsync, GitLab gitlab-backup-cli, Mailcow vmail-rsync, MSSQL BACKUP DATABASE lokal + Pull |
30d | Restic auf VM-HM-BACKUP-01 |
| L4 | NAS → Lager-NAS Snapshot-Replikation (zfs send) | 90d/12m | Lager-NAS |
| L5 | Quartalsweise Restore-Test in Sandbox-VM (CI-Job) | — | Wiki-Eintrag |
Restic statt Borg (S3-native, MinIO-passend, parallele Repos einfacher).
/health, /api/v1/status, OIDC-Discovery-URL etc.). Wo Health-Endpoint nicht existiert: HTTP-Status-Code-Probe + Cert-Expiry.@blackreset-prod-alerts, @blackreset-test).m@blackreset.com, server@blackreset.com als to-inform.Zwei Registries — strikt getrennte Rollen:
reg.git.blackreset.com)gitlab-built/<project>:<tag>).reg.git.blackreset.com bleibt erhalten. Volume mit GitLab-Backup mitgesichert.harbor.blackreset.internal)docker.io, ghcr.io, quay.io + Vulnerability-Scan (Trivy)./etc/docker/config.json).Ergebnis: CI-built Images bei GitLab, Upstream-Images bei Harbor. Keine Vermischung.
Jede Phase: (a) Plan im Wiki, (b) Skript, das ohne Aufsicht laufen kann, (c) Verify-Skript.
| Phase | Titel | Aufsicht | Vorbedingung |
|---|---|---|---|
| 0 | Plan-Approval + Naming-Lock + Hetzner-IP-Audit + AD↔Authentik-Diff + VM-SL-05/06/09-Audit | volle Aufsicht | — |
| 1 | Standard-Image: Debian 13 + Cloud-Init + Ansible-Repo infra/baseline testen |
mittel | 0 |
| 2 | VM-RZ-REG-01 (Harbor) live + Authentik-OIDC-Templates fertig | mittel | 1 |
| 3 | VM-RZ-DB-01 hochziehen (PG + MariaDB Container leer). MSSQL-Audit auf VM-DB-02 | wenig | 1 |
| 4 | MSSQL → Postgres-Migration | mittel | 3 |
| 5 | VM-RZ-EDGE-01 (Traefik+CrowdSec) parallel zu altem, DNS-TTL-Switch | mittel | 1 |
| 6 | VM-RZ-MAIL-01 mit gleicher Mail-IP, Mailcow-Daten via helper-scripts/backup, Floating-IP-Switch |
volle Aufsicht | 5 |
| 7 | NC + GitLab + Wiki-Plumbing als Container auf VM-RZ-SVC-PROD-01 (parallel-import, Cutover) — Auth ist schon gemacht (✓) | volle Aufsicht | 4, 6 |
| 8 | VM-RZ-APP-PROD-01 + STAGE-01 + GitLab-Runner. Self-built Apps (Radio, …) containerisieren + deployen | wenig | 7 |
| 9 | RZ-Decom: SL-02..09, DB-01, DB-02 (30d-Karenz). Audit-Reste | wenig | 8 |
| 10 | Home: VM-HM-DB-01, VM-HM-BACKUP-01, VM-HM-SVC-PROD-01, VM-HM-EDGE-01, VM-HM-APP-PROD-01, VM-HM-APP-STAGE-01 hochziehen | wenig | 1 |
| 11 | DC-Migration RZ → Home (VM-HM-DC-01) | volle Aufsicht | 7, 10 |
| 12 | VM-HM-SVC-PROD-02 (Plex/Tautulli/Immich/Tdarr) — Bestand migrieren, NAS-Mounts | wenig | 10 |
| 13 | VM-SW-03 → CUPS-Container auf VM-HM-SVC-PROD-01. Decom SW-03. Lancache decom. | mittel | 10 |
| 14 | Game-Server zentral nach VM-HM-GAME-01 (Pelican) | mittel | 12 |
| 15 | Home-Decom + Network-Tightening. pfSense Default-Deny enforce. | mittel | 13 |
| 16 | ESXi → Proxmox RZ. Letzter Schritt. Eigene Plan-Seite | volle Aufsicht | 9, 15 |
Ab Phase 5 sind viele Schritte parallelisierbar, wenn Aufsicht da ist.
| Service | Aktuell (Host-VM) | Ziel-VM | Engine | Daten-Migration | Auth | Phase |
|---|---|---|---|---|---|---|
| Authentik | vm-sl-00 | VM-RZ-SVC-PROD-01 | Container | DB → VM-RZ-DB-01 | self | 7 |
| BookStack-Legacy | vm-sl-08 | RO-Archiv auf SVC-PROD-01 | Container | Export → Wiki.js (✓) | OIDC | done |
| CUPS (Drucker) | VM-SW-03 | VM-HM-SVC-PROD-01 | Container | Druckerqueues exportieren | local | 13 |
| Dashboard (Homepage) | (neu) | VM-HM-SVC-PROD-01 | Container | YAML-in-Git | OIDC | 10 |
| Game-Server | RZ-GameVMs | VM-HM-GAME-01 (Pelican) | Container | Welt-Saves rsync | Pelican | 14 |
| GitLab CE | VM-SL-04 (omnibus) | VM-RZ-SVC-PROD-01 | Container | gitlab-backup-cli + DB→DB-01 | OIDC ✓ | 7 |
| GitLab Container Reg | VM-SL-04 | VM-RZ-SVC-PROD-01 | Container | Volume rsync | self | 7 |
| Harbor (Proxy-Cache) | (neu) | VM-RZ-REG-01 | Container | leer hochziehen | local | 2 |
| Home Assistant | VM-HA | unverändert | Native | — | — | — |
| Immich | (vorhanden ggf.) | VM-HM-SVC-PROD-02 | Container | Daten + DB | OIDC | 12 |
| Lancache | Home | DECOM | — | — | — | 13 |
| Mailcow | VM-SL-02 | VM-RZ-MAIL-01 | Container | helper-scripts/backup | local | 6 |
| MariaDB-legacy | VM-DB-01 | VM-RZ-DB-01 (Container) | Container | mysqldump + import | n/a | 3 |
| MSSQL | VM-DB-02 | VM-RZ-DB-01 PG | Container | pgloader / pgdump-Archiv | n/a | 4 |
| Nextcloud | VM-SL-03 | VM-RZ-SVC-PROD-01 | Container | files-rsync + DB→DB-01 | OIDC ✓ | 7 |
| Paperless-ngx | — | gestrichen | — | — | — | — |
| Plex | (vorhanden) | VM-HM-SVC-PROD-02 | Container | Library rsync + plex-claim | Plex SSO | 12 |
| Postgres-legacy | VM-DB-01 | VM-RZ-DB-01 (Container) | Container | pg_dumpall + import | n/a | 3 |
| Radio (AzuraCast) | VM-SL-06 (Docker) | VM-RZ-APP-PROD-01 | Container | Compose + Volumes + DB → DB-01 | OIDC* | 8 |
| Tautulli | (vorhanden) | VM-HM-SVC-PROD-02 | Container | Config rsync | OIDC | 12 |
| Tdarr | (vorhanden) | VM-HM-SVC-PROD-02 | Container | Lib + Flow | local | 12 |
| Traefik (RZ) | (verstreut) | VM-RZ-EDGE-01 | Container | neue Config | — | 5 |
| Traefik (Home) | (vorhanden) | VM-HM-EDGE-01 | Container | neue Config | — | 10 |
| Unifi-Network-Ctrl | (Bestand) | VM-HM-SVC-PROD-01 | Container | mongo-dump | local | 10 |
| Uptime Kuma | (vorhanden) | VM-HM-SVC-PROD-01 (main) + RZ-Slave | Container | Export → Re-Strukturieren | OIDC | 10 |
| Vaultwarden | (neu) | VM-RZ-SVC-PROD-01 | Container | — | OIDC | 10 |
| Wiki.js | vm-sl-00 | unverändert | Container | — | OIDC | done |
Alle VMs Debian 13 minimal, virtio NIC, virtio-scsi, EFI/UEFI, secure-boot off, qemu-guest-agent. „Disks" sind getrennte virtuelle Disks (eigenes LVM-PV pro Disk → eigenes VG → eigenes LV pro Daten-Volume).
| VM | vCPU | RAM | Disk-1 (OS) | Disk-2 (Daten) | Disk-3 (extra) | VLAN | Bemerkung |
|---|---|---|---|---|---|---|---|
| VM-RZ-EDGE-01 | 2 | 4 GB | 30 GB | — | — | 300 | Traefik+CrowdSec Logs als ringbuffer |
| VM-RZ-MAIL-01 | 4 | 8 GB | 40 GB | 200 GB (vmail) | — | 200 | dedizierte Mail-IP, niemals NAT-shared |
| VM-RZ-SVC-PROD-01 | 8 | 24 GB | 60 GB | 3000 GB (NC files) | 200 GB (GitLab repos+reg) | 200 | NC-Daten separat — direkt 3 TB initial (wird eher mehr, online vergrößerbar) |
| VM-RZ-SVC-TEST-01 | 2 | 4 GB | 40 GB | 60 GB | — | 200 | OK wenn down |
| VM-RZ-APP-PROD-01 | 4 | 8 GB | 40 GB | 100 GB | — | 200 | + GitLab-Runner-Workdir |
| VM-RZ-APP-STAGE-01 | 4 | 8 GB | 40 GB | 100 GB | — | 200 | + GitLab-Runner-Workdir |
| VM-RZ-DB-01 | 4 | 16 GB | 40 GB | 200 GB (PG /var/lib/...) |
100 GB (MariaDB) | 100 | LVM-Snapshots vor Schema-Migrations |
| VM-RZ-REG-01 | 2 | 8 GB | 30 GB | 500 GB (Harbor-Cache) | — | 100 | Proxy-Cache, kein CI-Push-Ziel |
RZ-Summe: 30 vCPU / 80 GB RAM / ~3.3 TB Disk (Steady State, ohne RZ-Game-Reste).
| VM | vCPU | RAM | Disk-1 (OS) | Disk-2 (Daten) | Disk-3 (extra) | VLAN | Bemerkung |
|---|---|---|---|---|---|---|---|
| VM-HM-DC-01 | 2 | 4 GB | 60 GB | — | — | 1000 | AD minimal, Windows Server 2022 (oder Samba? siehe Frage 5) |
| VM-HM-EDGE-01 | 2 | 4 GB | 30 GB | — | — | 1500 | Traefik+CrowdSec+dyn-DNS |
| VM-HM-SVC-PROD-01 | 4 | 12 GB | 40 GB | 150 GB | — | 1000 | UptimeKuma main, Homepage, CUPS, Unifi, weitere |
| VM-HM-APP-PROD-01 | 4 | 12 GB | 40 GB | 150 GB | — | 1000 | reine App-VM, kein Runner |
| — | — | — | — | — | — | DROPPED 2026-05-02 — builds happen on VM-HM-APP-STAGE-01 | |
| VM-HM-DB-01 | 4 | 12 GB | 40 GB | 200 GB (PG) | 100 GB (MariaDB) | 1000 | eigenständig, keine Repl |
| VM-HM-SVC-PROD-02 | 6 | 16 GB | 40 GB | 200 GB (App-State) | NAS-Mount (Plex-Library) | 1000 | Tdarr nur Movies/Series, niemals Photos |
| VM-HM-BACKUP-01 | 2 | 8 GB | 40 GB | 100 GB (App+Indexes) | NAS-NFS/SMB + ext. virtio | 1000 | Databasement; Storage extern eingebunden, keine fette VHD; kein MSSQL-Direkt-Zugriff |
| VM-HM-GAME-01 | 6 | 16 GB | 40 GB | 300 GB | — | 1000 | Pelican Panel, später (Phase 14) |
Home-Summe: 36 vCPU / 100 GB RAM / ~1.4 TB virtuelle Disk + NAS-Mounts (Plex-Lib, Backup-Targets) + ext. Storage für Databasement.
| VM | Bemerkung |
|---|---|
| VM-TS-12 | Alex' Main / Claude-Host, freie Firewall-Regeln |
| VM-HA | Home Assistant |
| VM-SW-03 | Decom in Phase 13 (Druck → CUPS-Container) |
NC-Daten-Trend: Alex 4.7 TB heute → 1.5 TB Disk-2 angesetzt für SVC-PROD-01 ist initial; Plan ist Volume online vergrößerbar (LVM + qcow2 resize). Wenn schneller wachsend dimensionieren wir hoch oder Daten auf NAS-NFS-Mount auslagern.
# tools/onboard-vm.sh <vmname> <vlan-ip>
# - schreibt ~/.ssh/config Eintrag
# - kopiert standard-pubkey auf VM
# - lädt Ansible-baseline-Playbook und führt es aus (apt + docker + node_exporter + promtail + kuma-push)
# - registriert VM in Uptime-Kuma + Authentik-LDAP-Outpost
# - pingt Telegram via Kuma-Notification-Test
Implementierungs-Plan: Phase 1 zusammen mit infra/baseline-Repo.
| Punkt | Status |
|---|---|
| 0.5 Auth = Authentik, Apps niemals an DC | locked |
| 0.8 Uptime-Kuma darf pollen | locked, Polling + Push parallel |
| Naming | locked |
| EDGE als einziger Web-Eintritt + Wildcard-Pipeline | erklärt §2.1 + §5.1 |
| UptimeKuma-Hauptinstanz Home | locked, Slave bleibt im RZ |
| GitLab-Runner auf VM-RZ-APP-PROD-01 + VM-HM-APP-PROD-01 | locked |
| Radio = AzuraCast (heute auf SL-06) | aufgenommen §13, Migration → VM-RZ-APP-PROD-01 in Phase 8 |
| CrowdSec erklärt + auch auf HM-EDGE-01 | erklärt §2.1, beide Sites |
Default-Mail m@ + to-inform server@ |
locked §8 |
| MON in SVC-PROD-01 | locked |
| „Bastion" gestrichen | nur noch SSH via S2S-VPN aus Home; kein eigener Jump-Host |
| AD-Strategie + AD↔Authentik connected via LDAP-Source | korrigiert §3.3 + §7 |
| NC extra Disk | aufgenommen §14 (1.5 TB getrennte Disk) |
| Audit VM-SL-05/06/09 | Pflicht in Phase 0 — ToDo |
| Vaultwarden in RZ | locked §13 |
| Paperless gestrichen | locked |
| VM-HM-DB-01 unabhängig | locked, keine Repl |
| Lancache decom | locked |
| Game-Server nach Home (max 4 Player) | locked |
| Homepage als Heimdall-Alt | locked |
| Unifi-Controller + weitere Home-Services | aufgenommen §3.2 — Liste pending → Frage 4 |
| RZ + HM Netz-Topologie konkret | locked §4.1 + §4.2 |
| LAB → EDGE Rebuild, IP-Bereiche frei | locked |
| DB unabhängig, kein Repl, Backup ins Databasement | locked §5 |
| 2 DB-Server | locked |
blackreset.internal überall (außer Windows-xio.bio) |
locked §0.10, Firewalls auch |
| Apps weiterhin auf Public-Domain | locked |
| Databasement kein MSSQL-Zugriff | korrigiert §6 + §9 |
| NC + GitLab Auth done | dokumentiert §7 |
| Ansible OK, kein Server nötig | erklärt §8.1 |
| Telegram in Kuma reicht, Health-Endpoints nutzen | locked §10 |
GitLab-Registry reg.git.blackreset.com bleibt |
locked §11.1 (getrennt von Harbor) |
| Q1 Site-Idee | OK |
| Q3 Mailcow-Cutover-Fenster „wenn es soweit ist" | OK, Termin spät |
| Q4 MSSQL-Audit Phase 0 starten | OK |
| Q5 Homepage | OK |
| Q6 Build-Runner Home | „was meinst du damit" → Klärung in Frage 2 |
| Q7 Watchtower opt-in | OK |
| Q8 Game max 4 Spieler selten | OK |
| Q9 Drucker = Brother MFA, IPs in pfSense | OK, Modelle aus Web-UI lesen vor Phase 13 |
| Q10 Hetzner-IPs in Firewall | OK, Phase-0-Skript inventarisiert sie automatisch |
| Risiko | Wahrsch. | Impact | Mitigation |
|---|---|---|---|
| Mail-IP-Reputation kaputt durch IP-Wechsel | mittel | hoch | Niemals Mail-IP wechseln. Floating-IP migrieren. |
| App-User-Mismatch beim OIDC-Cutover (Lessons Learned NC/GitLab) | mittel | hoch | Pre-Migration-Audit Skript pro App, immer UUID als Join-Key. |
| Crypto-Key-Spalten beim uid-Rename versehentlich gelöscht | mittel | hoch | NIE oc_otpmanager_settings.password/iv etc. anfassen. Backup vor jedem Rename. |
| GitLab-Postgres-Migration verliert Pipelines/Repos | mittel | hoch | gitlab-backup-cli + 30d-Karenz, Stage-Trockenlauf |
| S2S-VPN aus → DC weg → kein RZ-App-Login | niedrig | niedrig | Authentik braucht DC nur für periodischen Sync, nicht Login (locked §3.3) |
| Watchtower bricht Prod-Service | mittel | mittel | Opt-in only; Renovate für Prod |
| Decom zu früh: noch genutzte VM gelöscht | niedrig | hoch | 30-Tage-Karenz powered-off; Audit-Log |
| pgloader-Schema-Mismatch | mittel | mittel | Trockenlauf + Daten-Diff |
| Home-Bandbreite zu klein für Media+Game gleichzeitig | niedrig | mittel | Game selten + max 4 Player; QoS in pfSense |
| Wildcard-Cert-Renewal bricht | niedrig | hoch | DNS-01 via Hetzner-API, Monitoring auf Cert-Ablauf <14d |
Draft → Approved mit Datum.| Q | Frage | Antwort |
|---|---|---|
| 1 | VM-HM-BUILD-01 sparen? | Ja, gespart — Build-Runner-Funktion läuft auf VM-HM-APP-STAGE-01 (Decision Alex 2026-05-02). |
| 2 | Runner-Netzrichtung | Bestätigt. Runner connected outbound zu git.blackreset.com, pollt Jobs. Kein Inbound. |
| 3 | Radio | AzuraCast, läuft heute auf VM-SL-06 in Docker → Migration auf VM-RZ-APP-PROD-01 in Phase 8. |
| 4 | Home-Services-Liste | Wichtigstes ist erfasst. Rest wird per VM-Decom-Audit (Phase 9/13/15) inventarisiert + verschoben. |
| 5 | DC-Engine | 1:1-VM-Move der bestehenden Windows-DC, kein OS-Wechsel. |
| 6 | NC-Disk-Größe | 3 TB initial (eher mehr werden, online vergrößerbar). §14 entsprechend gesetzt. |
| 7 | Databasement-Disk | Nicht 4 TB intern — virtuelle Disk klein (100 GB für App+Indexes), Backup-Storage per NAS-Mount + ext. virtio-Disk angebunden. |
| 8 | EDGE-IP | Klärung pending — siehe Frage unten. |
| 9 | Audit VM-SL-05/06/09 | Go. Phase-0-Skripte werden gebaut und gegen die VMs gefahren. |
| 10 | Hetzner-IP-Audit | Go. tools/audit/hetzner-floating-ips.py (read-only hcloud). |
.246. Saubere Trennung — .248 bleibt während Cutover für die alten Prod-Services als Failback.*.blackreset.com) und User-facing-Records (cloud., git., wiki., auth., …) zeigen aktuell auf .248; in Phase 5 wird der TTL kurz runtergesetzt und die DNS-Records einzeln auf .246 umgeswitcht — so wandert pro Service nach Verifikation und nicht in einem Big-Bang.Debian-Installer:
vm-rz-edge-01 (lowercase, kein FQDN, keine Domain dran).rz.blackreset.internal — ergibt hostname -f = vm-rz-edge-01.rz.blackreset.internal und matcht §1 Infra-DNS.Domain-Feld leer lassen ist OK falls interner DNS noch nicht steht — die Ansible-Baseline (Phase 1) setzt es nach.
Update 2026-05-02 (Alex): Naming relock — VM-HM-SVC-01/02 → VM-HM-SVC-PROD-01/02 (consistent with -PROD-/-STAGE- suffix used for RZ). VM-HM-BUILD-01 explicitly dropped — building happens on VM-HM-APP-STAGE-01. See
/policies/ip-allocation-hmfor full IP map.