User Tools

Site Tools


infrastructure:bootstrap

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
infrastructure:bootstrap [2026/02/09 14:03] mxminfrastructure:bootstrap [2026/02/10 20:44] (current) – big rewrite to ansible mxm
Line 1: Line 1:
 ====== Bootstrap Guide ====== ====== Bootstrap Guide ======
  
-Komplettanleitung zum Aufbau des Automation Stacks von Grund auf. Wir haben hier als Standard-Fall die Installation im lokalen Netzwerk dokumentiert. Parallel teste ich aber auch auf einem preiswerten VPS auf Hetzner im Projekt //mxmlabs-test//, daher manchmal wo notwendig Abweichungen+Komplettanleitung zum Aufbau des Automation Stacks von Grund auf.
  
 ===== Übersicht ===== ===== Übersicht =====
Line 9: Line 9:
 ─────────────────        ─────────────────────         ────────── ─────────────────        ─────────────────────         ──────────
 Proxmox                  bootstrap.sh                  Operations Proxmox                  bootstrap.sh                  Operations
-UniFi Netzwerk           └─► LXCs erstellen            • Monitoring +Cloudflare               └─► LXCs erstellen            • Monitoring 
-Cloudflare               └─► Services deployen         • Backups +vault.yml                └─► Services deployen         • Updates 
-vault.yml                └─► Secrets migrieren         • Updates+Inventory wählen         └─► Firewall-Regeln           • Ansible
 </code> </code>
  
 ===== DAY 0 — Foundation ===== ===== DAY 0 — Foundation =====
  
-==== Netzwerk ====+==== Inventory Environment wählen ====
  
-=== UniFi ===+Der Stack unterstützt mehrere Environments über Inventory-Dateien:
  
-**VLAN anlegen:**+  * **Home environment**: ''ansible/inventory.yml'' (default) 
 +    Netzwerk: 10.100.161.0/24 
 +    Proxmox node: "pve" 
 +    * Domain: home.miskam.xyz 
 +  * **Hetzner environment**: ''ansible/inventory-hetzner.yml'' 
 +    * Netzwerk: 10.10.10.0/24 
 +    * Proxmox node: "hv-test" 
 +    * Domain: test.miskam.xyz
  
-^ VLAN ^ Name ^ Subnet ^ Gateway ^ +**Eigenes Environment hinzufügen:**
-| 160 | Server | 10.100.160.0/23 | 10.100.161.254 |+
  
-**Firewall-Regeln:**+<code bash> 
 +# 1. Inventory kopieren 
 +cp ansible/inventory.yml ansible/inventory-production.yml
  
-^ Regel ^ Von ^ Nach ^ Port ^ Aktion ^ +# 2Anpassen 
-| WAN-HTTP | WAN | 10.100.161.102 | 80,443 | Allow | +vim ansible/inventory-production.yml 
-| VPN-Server | 192.168.7.0/24 | 10.100.160.0/23 | * | Allow | +</code>
-| Server-LAN | 10.100.160.0/23 | LAN | * | Allow |+
  
-**Port-Forwarding:**+In der Inventory-Datei definieren: 
 +  ''network.prefix'': z.B. "10.20.30" → Container bekommen 10.20.30.110-117 
 +  * ''network.gateway''Gateway des Netzwerks 
 +  ''domain'': Basis-Domain für Services 
 +  ''proxmox.hosts'': Proxmox-Host und IP 
 +  * ''automation_stack.hosts'': Container-IDs und Hostnames
  
-^ Extern ^ Intern ^ Service ^ +Beispiel Hetzner: 
-| 80 | 10.100.161.102:80 | Traefik HTTP | +<code yaml> 
-| 443 | 10.100.161.102:443 | Traefik HTTPS |+all: 
 +  vars: 
 +    network: 
 +      prefix: "10.10.10" 
 +      gateway"10.10.10.1" 
 +      nameserver: "10.10.10.1" 
 +    domaintest.miskam.xyz 
 + 
 +  children: 
 +    proxmox: 
 +      hosts: 
 +        hv-test: 
 +          ansible_host: 91.107.196.96 
 + 
 +    automation_stack: 
 +      hosts: 
 +        traefik: 
 +          ct_id: 110 
 +          ct_hostname: traefik 
 +          # ... weitere Container 
 +</code>
  
 ==== Cloudflare ==== ==== Cloudflare ====
  
 **Domain hinzufügen:** **Domain hinzufügen:**
-  - home.miskam.xyz → Cloudflare DNS+  - Domain → Cloudflare DNS
  
 **API Token erstellen:** **API Token erstellen:**
   - My Profile → API Tokens → Create Token   - My Profile → API Tokens → Create Token
   - Template: "Edit zone DNS"   - Template: "Edit zone DNS"
-  - Zone: home.miskam.xyz+  - Zone: Deine Domain
   - → Token speichern für vault.yml   - → Token speichern für vault.yml
  
Line 53: Line 85:
 ^ Type ^ Name ^ Value ^ ^ Type ^ Name ^ Value ^
 | A | *.home.miskam.xyz | <WAN-IP> | | A | *.home.miskam.xyz | <WAN-IP> |
 +| A | *.test.miskam.xyz | <Hetzner-IP> |
  
 ==== Proxmox ==== ==== Proxmox ====
  
-=== lokal === +=== lokal (Home) ===
  
 **Installation:** **Installation:**
Line 75: Line 106:
     bridge-vlan-aware yes     bridge-vlan-aware yes
 EOF EOF
-ifreload -a +ifreload -a
 </code> </code>
  
-=== Hetzner ===+=== Hetzner VPS === 
 + 
 +**NAT-Setup für private Netzwerk:**
  
 <code> <code>
Line 86: Line 119:
  
 auto eno1 auto eno1
-#real IP address +iface eno1 inet static 
-iface nic0 inet static +        address  91.107.196.96/24 
-        address  198.51.100.5/24 +        gateway  91.107.196.1
-        gateway  198.51.100.1+
  
 auto vmbr0 auto vmbr0
-#private sub network 
 iface vmbr0 inet static iface vmbr0 inet static
         address  10.10.10.1/24         address  10.10.10.1/24
Line 104: Line 135:
 EOF EOF
 ifreload -a ifreload -a
 +</code>
 +
 +**Port-Forwarding** (Ports 80/443 → Traefik):
 +
 +Nach Bootstrap einmalig ausführen:
 +<code bash>
 +cd ansible
 +ansible-playbook configure-nat.yml --vault-password-file ../.vault_pass
 </code> </code>
  
Line 110: Line 149:
   * User: root@pam   * User: root@pam
   * Token ID: ansible   * Token ID: ansible
-  * Privilege Separation: aus+  * **Privilege Separation: aus** (wichtig!)
   * → Token speichern für vault.yml   * → Token speichern für vault.yml
- 
-==== Ops Container einrichten (OpenClaw) ==== 
-<code> 
-pveam download local debian-13-standard_13.1-2_amd64.tar.zst 
- 
-TEMPLATE="local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst" 
- 
-pct create 100 $TEMPLATE --hostname ops --memory 2048 --cores 2 \ 
-  --rootfs local-lvm:16 --net0 name=eth0,bridge=vmbr0,ip=10.10.10.2/24,gw=10.10.10.1 \ 
-  --features nesting=1 --unprivileged 1 --start 1 
- 
-# install curl, requirement for the openclaw installer 
-pct exec 100 -- bash -c "apt update && apt install curl -y" 
-# install openclaw (unconfigured) 
-pct exec 100 -- bash -c "curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard" 
-# install uv  
-pct exec 100 -- bash -c  "curl -LsSf https://astral.sh/uv/install.sh | sh" 
-# add uv to $PATH 
-pct exec 100 -- bash -c "/root/.local/bin/uv tool update-shell" 
-# install ansible 
-pct exec 100 -- bash -c "/rrot/.local/bin/uv tool install ansible-core" 
-pct exec 100 -- bash -c "/root/.local/bin/uv tool install --with proxmoxer --with requests ansible" 
- 
- 
- 
-</code> 
- 
  
 ==== vault.yml vorbereiten ==== ==== vault.yml vorbereiten ====
- 
-Alle Secrets für den Bootstrap in einer Datei: 
  
 <code bash> <code bash>
-cd ansible/ +# 1. Vault-Passwort erstellen 
-cat vault.yml.plain << 'EOF' +echo 'dein-sicheres-passwort' > .vault_pass 
-# Proxmox +chmod 600 .vault_pass
-vault_proxmox_api_user: "root@pam!ansible" +
-vault_proxmox_api_token: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"+
  
-Cloudflare +2. Vault generieren (mit Platzhaltern) 
-vault_cloudflare_token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"+./bootstrap.sh --generate-vault
  
-PostgreSQL +3. Anpassen 
-vault_postgresql_admin: "GENERATE_ME" +vim vault.yml 
-vault_postgresql_n8n: "GENERATE_ME" +</code>
-vault_postgresql_vaultwarden: "GENERATE_ME" +
-vault_postgresql_forgejo: "GENERATE_ME"+
  
-# Services +**Pflichtfelder:** 
-vault_vaultwarden_admin_token"GENERATE_ME" +  * ''cloudflare_email''Cloudflare Account Email 
-vault_n8n_encryption_key"GENERATE_ME" +  * ''cloudflare_api_token''API Token von Cloudflare 
-vault_grafana_admin: "GENERATE_ME+  * ''proxmox_api_token_secret''Token-Secret von Proxmox 
-vault_dokuwiki_admin"GENERATE_ME"+  * ''proxmox_node'': Node-Name ("pveoder "hv-test") 
 +  * ''domain''Muss mit Inventory übereinstimmen
  
-# Bot User (für Vaultwarden nach Migration+**Optional (werden auto-generiert):** 
-vault_bot_email: "mxm-[email protected]" +  * Alle Passwörter und Encryption Keys 
-vault_bot_password: "GENERATE_ME" +  * ''proxmox_storage''Default "local-lvm"
-EOF+
  
-Secrets generieren +<code bash> 
-sed -i "s/GENERATE_ME/$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c24)/g" vault.yml.plain +4. Verschlüsseln 
- +./bootstrap.sh --encrypt
-Verschlüsseln +
-ansible-vault encrypt vault.yml.plain --output vault.yml +
-rm vault.yml.plain+
 </code> </code>
  
 ===== DAY 1 — Bootstrap ===== ===== DAY 1 — Bootstrap =====
  
-==== Voraussetzungen ====+==== Bootstrap starten ====
  
-  Proxmox erreichbar (SSH + API) +**Home environment (default):*
-  Netzwerk konfiguriert (VLAN 160) +<code bash> 
-  * vault.yml verschlüsselt vorhanden +./bootstrap.sh 
-  * Git-Repo geklont+</code>
  
-==== 1.1 Bootstrap starten ====+**Hetzner environment:** 
 +<code bash> 
 +INVENTORY_FILE=ansible/inventory-hetzner.yml ./bootstrap.sh 
 +</code>
  
 +**Eigenes environment:**
 <code bash> <code bash>
-cd ansible/ +INVENTORY_FILE=ansible/inventory-production.yml ./bootstrap.sh
-./bootstrap.sh +
-# → Vault-Passwort eingeben+
 </code> </code>
  
Line 201: Line 206:
 bootstrap.sh bootstrap.sh
     │     │
-    ├─► 1. Control Node (CT 103) +    ├─► 1. Validierung 
-    │       ── Ansible, Git, SSH-Key+    │       ├── Cloudflare API 
 +    │       ├── SSH Keys 
 +    │       └── vault.yml
     │     │
-    ├─► 2. Traefik (CT 102+    ├─► 2. LXC Container (via Proxmox API) 
-    │       └── CF-Token, Wildcard-Cert+    │       ├── Traefik (110) 
 +    │       ├── PostgreSQL (111) 
 +    │       ├── n8n (112) 
 +    │       ├── Vaultwarden (113) 
 +    │       ├── DokuWiki (114) 
 +    │       ├── Uptime Kuma (115) 
 +    │       ├── Monitoring (116
 +    │       └── Forgejo (117)
     │     │
-    ├─► 3. PostgreSQL (CT 110) +    ├─► 3. SSH Key Injection 
-    │       └── DBs: n8n, vaultwarden, forgejo+    │       └── Alle Container SSH-fähig
     │     │
-    ├─► 4. Vaultwarden (CT 112) +    ├─► 4. Base Packages 
-    │       └── Admin-Token konfiguriert+    │       └── curl, git, ufw, etc.
     │     │
-    ├─► 5. Services (parallel+    ├─► 5. Service Deployment 
-    │       ├── n8n (CT 111+    │       ├── Traefik (Reverse Proxy + SSL) 
-    │       ├── DokuWiki (CT 113+    │       ├── PostgreSQL (Shared DB
-    │       ├── Uptime Kuma (CT 114+    │       ├── n8n (Workflow Automation) 
-    │       ├── Monitoring (CT 115+    │       ├── Vaultwarden (Password Manager
-    │       └── Forgejo (CT 116)+    │       ├── DokuWiki (Wiki
 +    │       ├── Uptime Kuma (Monitoring
 +    │       ├── Prometheus + Grafana (Metrics
 +    │       └── Forgejo (Git Server)
     │     │
-    ─► 6. Traefik-Routen +    ─► 6. Firewall-Regeln 
-    │       └── automation.yml deployen +            └── Automatisch pro Service
-    │ +
-    ├─► 7. /etc/hosts +
-    │       └── *.srv.internal auf allen Hosts +
-    │ +
-    ├─► 8. node_exporter +
-    │       └── Port 9100 auf allen Hosts +
-    │ +
-    └─► 9. migrate-secrets.yml +
-            └── vault.yml → Vaultwarden API+
 </code> </code>
 +
 +**Dauer:** 15-20 Minuten (abhängig von Netzwerk-Geschwindigkeit)
  
 ==== Container-Übersicht ==== ==== Container-Übersicht ====
  
-^ CT ^ Name ^ IP ^ RAM ^ Disk ^ Port +^ CT ^ Name ^ IP (Suffix) ^ RAM ^ Disk ^ Ports 
-102 | traefik | 10.100.161.102 | 512M | 2G | 80,443 | +110 | traefik | .110 | 512M | 2G | 80,443,2222,8080 
-103 | openclaw | 10.100.160.249 | 2G | 8G | 18789 | +111 | postgres | .111 | 1G | 8G | 5432 | 
-| 110 | postgres | 10.100.161.110 | 1G | 8G | 5432 | +112 | n8n | .112 | 1G | 4G | 5678 | 
-111 | n8n | 10.100.161.111 | 1G | 4G | 5678 | +113 | vaultwarden | .113 | 512M | 2G | 8080 | 
-112 | vaultwarden | 10.100.161.112 | 512M | 2G | 8080 | +114 | dokuwiki | .114 | 512M | 2G | 80 | 
-113 | dokuwiki | 10.100.161.113 | 512M | 2G | 80 | +115 | uptime-kuma | .115 | 512M | 2G | 3001 | 
-114 | uptime-kuma | 10.100.161.114 | 512M | 2G | 3001 | +116 | monitoring | .116 | 1G | 4G | 9090,3000 | 
-115 | monitoring | 10.100.161.115 | 1G | 4G | 9090,3000 | +117 | forgejo | .117 | 512M | 4G | 3000 |
-116 | forgejo | 10.100.161.116 | 512M | 4G | 3000 |+
  
-==== Abhängigkeiten ====+IP-Suffix wird an ''network.prefix'' aus Inventory angehängt. 
 +Beispiel: Home 10.100.161.110, Hetzner 10.10.10.110
  
-<code> +==== Firewall-Regeln (automatisch) ====
-                    Proxmox + UniFi + Cloudflare +
-                              │ +
-                              ▼ +
-                    ┌─────────────────┐ +
-                    │   vault.yml     │ +
-                    └────────┬────────┘ +
-                             │ +
-              ┌──────────────┼──────────────┐ +
-              ▼              ▼              ▼ +
-        ┌──────────┐  ┌──────────┐  ┌──────────┐ +
-        │ Control  │  │ Traefik  │  │PostgreSQL│ +
-        │  Node    │  │   102    │  │   110    │ +
-        └────┬─────┘  └────┬─────┘  └────┬─────┘ +
-             │             │             │ +
-             │             │             ▼ +
-             │             │      ┌──────────┐ +
-             │             │      │Vaultwarden│ +
-             │             │      │   112    │ +
-             │             │      └────┬─────┘ +
-             │             │           │ +
-             │      ┌──────┴───────────┴──────┐ +
-             │      ▼      ▼      ▼     ▼     ▼ +
-             │   ┌─────┐┌─────┐┌─────┐┌─────┐┌─────┐ +
-             │   │ n8n ││Wiki ││Kuma ││Graf.││Forge│ +
-             │   │ 111 ││ 113 ││ 114 ││ 115 ││ 116 │ +
-             │   └──┬──┘└──┬──┘└──┬──┘└──┬──┘└──┬──┘ +
-             │      └──────┴──────┴──────┴──────┘ +
-             │                   │ +
-             ▼                   ▼ +
-      ┌────────────┐     ┌────────────┐ +
-      │ /etc/hosts │     │  Traefik   │ +
-      │*.srv.intern│     │   Routes   │ +
-      └────────────┘     └────────────┘ +
-                              │ +
-                              ▼ +
-                    ┌─────────────────┐ +
-                    │ migrate-secrets │ +
-                    │ → Vaultwarden   │ +
-                    └─────────────────┘ +
-</code>+
  
-===== DAY 2 — Operations =====+Jeder Service konfiguriert seine eigenen Firewall-Regeln:
  
-Nach erfolgreichem Bootstrap:+  * **PostgreSQL (111)**Erlaubt 5432 von n8n, vaultwarden, forgejo 
 +  * **n8n (112)**: Erlaubt 5678 von traefik 
 +  * **Vaultwarden (113)**: Erlaubt 8080 von traefik 
 +  * **DokuWiki (114)**: Erlaubt 80 von traefik 
 +  * **Uptime Kuma (115)**: Erlaubt 3001 von traefik 
 +  * **Monitoring (116)**: Erlaubt 3000+9090 von traefik 
 +  * **Forgejo (117)**: Erlaubt 3000 von traefik 
 +  * **Alle Container**: node_exporter (9100) von monitoring
  
-  * **Secrets:** Vaultwarden (Bitwarden-Lookup aktiv) +Regeln werden automatisch beim Service-Deployment angewendet.
-  * **Monitoring:** Prometheus + Grafana +
-  * **Git:** Forgejo (lokales Repo-Mirror)+
  
-==== URLs ====+===== DAY 2 — Operations ===== 
 + 
 +==== Service-URLs ====
  
 ^ Service ^ URL ^ ^ Service ^ URL ^
-| n8n | https://n8n.home.miskam.xyz +| n8n | https://n8n.domain 
-| Vaultwarden | https://vault.home.miskam.xyz +| Vaultwarden | https://vault.domain 
-| DokuWiki | https://wiki.home.miskam.xyz +| DokuWiki | https://wiki.domain 
-| Uptime Kuma | https://status.home.miskam.xyz +| Uptime Kuma | https://status.domain 
-| Grafana | https://monitoring.home.miskam.xyz +| Grafana | https://monitoring.domain 
-| Forgejo | https://git.home.miskam.xyz |+| Forgejo | https://git.domain | 
 +| Traefik Dashboard | https://traefik.domain |
  
-==== Credentials ====+==== Ansible Operations ====
  
-Alle Zugangsdaten in Vaultwarden+**Alle Services neu deployen:** 
-  * **Organisation:** mxmlabs +<code bash> 
-  * **Collection:** Network Automation+cd ansible 
 +ansible-playbook site.yml --vault-password-file ../.vault_pass 
 + 
 +# Hetzner: 
 +ansible-playbook -i inventory-hetzner.yml site.yml --vault-password-file ../.vault_pass 
 +</code> 
 + 
 +**Einzelner Service:*
 +<code bash> 
 +ansible-playbook site.yml --limit n8n --vault-password-file ../.vault_pass 
 +</code> 
 + 
 +**Vault editieren:** 
 +<code bash> 
 +ansible-vault edit ../vault.yml --vault-password-file ../.vault_pass 
 +</code> 
 + 
 +**Connectivity testen:** 
 +<code bash> 
 +ansible automation_stack -m ping --vault-password-file ../.vault_pass 
 + 
 +# Hetzner: 
 +ansible -i inventory-hetzner.yml automation_stack -m ping --vault-password-file ../.vault_pass 
 +</code> 
 + 
 +===== Besonderheiten ===== 
 + 
 +==== Traefik Rate Limiting ==== 
 + 
 +  * **n8n**Kein Rate Limiting (80+ Assets beim ersten Laden) 
 +  * **Andere Services**: 100 req/s, burst 100 (global) 
 +  * **Auth Services**: 5 req/s, burst 10 (vaultwarden, grafana, forgejo) 
 + 
 +==== Traefik SSH Port ==== 
 + 
 +Traefik verwendet Port 2222 für SSH, weil Port 22 an Forgejo weitergeleitet wird (Git SSH). 
 + 
 +==== Container Teardown ==== 
 + 
 +Zum vollständigen Entfernen aller Container: 
 +<code bash> 
 +# Mit Bestätigung 
 +./teardown.sh --confirm 
 + 
 +# Oder direkt via Ansible 
 +cd ansible 
 +ansible-playbook teardown.yml --vault-password-file ../.vault_pass 
 +</code>
  
 ---- ----
  
-//Erstellt: 2026-02-07//+//Erstellt: 2026-02-07 | Aktualisiert: 2026-02-10//
  
infrastructure/bootstrap.1770645781.txt.gz · Last modified: by mxm