Infrastructure as Code im Homelab: Nie wieder manuell konfigurieren

Mit Ansible, Docker Compose und Git die gesamte Homelab-Infrastruktur als Code verwalten – reproduzierbar, versioniert und im Notfall in Minuten wiederhergestellt.

Das Problem mit manuellen Konfigurationen

Kennt man das Gefühl? Ein Server läuft seit Monaten stabil. Man erinnert sich vage, dass man damals irgendwelche Einstellungen vorgenommen hat – welche genau, das weiß man nicht mehr. Dann stirbt die SSD, der Container lässt sich nicht mehr starten, oder man möchte einfach die Konfiguration auf eine neue Maschine übertragen.

Stunden vergehen. Man durchsucht alte Terminal-Historien, halbvergessene Notizen, veraltete Dokumentationen. Am Ende hat man etwas, das halbwegs funktioniert – aber identisch mit dem Original ist es nicht.

Genau dieses Szenario löst Infrastructure as Code (IaC). Die gesamte Infrastruktur – Server-Konfiguration, installierte Dienste, Netzwerkregeln, Benutzer – wird als Textdateien in einem Git-Repository verwaltet. Reproduzierbar, versioniert, und im Notfall mit einem einzigen Befehl wiederherstellbar.

Die drei Säulen: Git, Ansible, Docker Compose

Ein solides Homelab-as-Code-Setup basiert auf drei Werkzeugen, die sich hervorragend ergänzen:

Git ist das Fundament. Jede Änderung an der Infrastruktur wird als Commit festgehalten. Man sieht, was wann geändert wurde, kann Änderungen rückgängig machen und unterschiedliche Konfigurationen in Branches verwalten. Ein privates Repository auf dem eigenen GitLab-Server (selbst natürlich als Code verwaltet) ist der logische Ort.

Ansible übernimmt die Konfiguration von Linux-Systemen. Es ist agentless – es braucht nur SSH-Zugang auf den Zielhosts – und beschreibt den gewünschten Zustand in YAML-Dateien (sogenannten Playbooks). Ansible ist idempotent: Ein Playbook kann man beliebig oft ausführen, das Ergebnis ist immer gleich.

Docker Compose verwaltet containerisierte Dienste. Eine compose.yml-Datei beschreibt, welche Container laufen, welche Ports gebunden sind, welche Volumes gemountet werden und wie die Dienste untereinander kommunizieren. Der gesamte Stack lässt sich mit docker compose up -d starten.

Praxisbeispiel: Homelab vom Nullpunkt aufbauen

Nehmen wir an, ein frisch aufgesetzter Server soll folgende Dienste bereitstellen: einen Reverse Proxy, eine Passwort-Management-Lösung, ein lokales Git, und eine KI-Instanz (wie im Artikel Lokale KI im Homelab beschrieben). Manuell wären das Stunden Arbeit. Mit IaC dauert es Minuten.

Das Repository hat folgende Struktur:

homelab/
├── ansible/
│   ├── inventory.yml          # Liste der Hosts
│   ├── playbooks/
│   │   ├── base.yml           # Grundkonfiguration (SSH, Updates, Firewall)
│   │   ├── docker.yml         # Docker-Installation
│   │   └── services.yml       # Dienste deployen
│   └── roles/
│       ├── common/
│       ├── docker/
│       └── monitoring/
├── docker/
│   ├── proxy/
│   │   └── compose.yml
│   ├── gitea/
│   │   └── compose.yml
│   ├── vaultwarden/
│   │   └── compose.yml
│   └── ollama/
│       └── compose.yml
└── README.md
BSS Server-Administration – professionell verwaltete Infrastruktur

Das Basis-Playbook sieht vereinfacht so aus:

# ansible/playbooks/base.yml
- name: Grundkonfiguration
  hosts: homelab
  become: true
  tasks:
    - name: System aktualisieren
      apt:
        upgrade: dist
        update_cache: true

    - name: Notwendige Pakete installieren
      apt:
        name:
          - ufw
          - fail2ban
          - htop
          - git
        state: present

    - name: Firewall konfigurieren
      ufw:
        rule: allow
        port: "{{ item }}"
      loop:
        - ssh
        - "80"
        - "443"

    - name: UFW aktivieren
      ufw:
        state: enabled
        policy: deny

Ausführen mit:

ansible-playbook -i ansible/inventory.yml ansible/playbooks/base.yml

Dienste als Docker Compose verwalten

Eine compose.yml für den Reverse Proxy könnte so aussehen:

services:
  proxy:
    image: caddy:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

Das Ansible-Playbook kopiert diese Datei auf den Server und startet den Stack – oder führt docker compose pull && docker compose up -d aus, wenn er bereits läuft. So werden Updates zum trivialen Einzeiler.

Geheimnisse sicher verwalten

Ein häufiger Stolperstein bei IaC: Passwörter und API-Keys dürfen nicht im Git-Repository landen. Bewährte Lösungen:

Ansible Vault verschlüsselt sensitive Variablen direkt in der Ansible-Konfiguration. Ein Master-Passwort entschlüsselt sie zur Laufzeit.

.env-Dateien werden für Docker Compose genutzt, aber in .gitignore aufgenommen. Eine .env.example ohne echte Werte zeigt, welche Variablen benötigt werden.

Dedizierte Secrets-Manager (selbst gehostete Vault-Lösungen) sind für größere Umgebungen empfehlenswert – sie bieten Audit-Logs, Rotation und feingranulare Zugriffssteuerung.

Disaster Recovery in der Praxis

Mit diesem Setup sieht ein vollständiges Disaster-Recovery-Szenario so aus:

  1. Neuen Server aufsetzen (frisches Debian/Ubuntu)
  2. SSH-Key hinterlegen
  3. git clone git@homeserver:homelab.git ausführen
  4. ansible-playbook -i inventory.yml playbooks/site.yml starten
  5. Kaffee trinken

Die Dienste sind nach 10–20 Minuten wieder vollständig betriebsbereit. Daten werden aus dem Backup wiederhergestellt (das selbstverständlich ebenfalls als Code konfiguriert und regelmäßig getestet ist). Gedanken zur Sicherheit der wiederhergestellten Infrastruktur finden sich im Artikel Zero Trust für KMU.

Einstieg: So fängt man an

Der häufigste Fehler ist der Versuch, die gesamte Infrastruktur auf einmal zu kodifizieren. Besser: klein anfangen.

Schritt 1: Ein Git-Repository anlegen und die erste compose.yml eines bereits laufenden Dienstes hineinlegen. Kein Ansible noch, kein CI/CD – einfach nur Versionierung.

Schritt 2: Ein einfaches Ansible-Playbook schreiben, das die Basis-Pakete eines neuen Servers installiert. An einer frischen VM testen.

Schritt 3: Schrittweise weitere Dienste migrieren. Dabei konsequent: Keine manuelle Änderung mehr ohne anschließenden Commit.

Nach wenigen Wochen hat man eine vollständige, versionierte Beschreibung der eigenen Infrastruktur – und das beruhigende Gefühl, dass ein Totalausfall kein Drama mehr wäre.

Mehr zu professioneller Server-Administration