[ OK ]Kernel wird initialisiert...
~/im/blog
Kontakt aufnehmen

Lass uns reden

Interesse an einer Zusammenarbeit oder eine Frage? Ich bin immer offen für neue Projekte.

Kontakt aufnehmen

Vernetzen

Finden Sie mich in sozialen Medien und auf beruflichen Netzwerken.

DatenschutzerklärungNutzungsbedingungen
© 2026 Irfan MiralEntwickelt vonirfanMiral.com
StartÜber mich/LebenslaufBlogKontakt
2026-02-19• 5 Min. Lesezeit

Warum Server-Configs in Git gehören, nicht in den Kopf

DevOps Git Infrastructure as Code Linux-Administration

Fast jeder Server, den ich übernehme, hat dasselbe stille Problem: Die Configs funktionieren, aber niemand kann sagen, warum sie so aussehen, wie sie aussehen. Ein Nginx-Vhost hat einen proxy_read_timeout, der auf 300 Sekunden hochgesetzt wurde. Eine fail2ban-Jail hat einen IP-Bereich auf der Whitelist. Ein sysctl-Wert verdoppelt ein Connection-Limit. Jede dieser Änderungen war wahrscheinlich zum jeweiligen Zeitpunkt die richtige Entscheidung, live gemacht, unter Druck, und danach nirgendwo dokumentiert außer in der Datei selbst. Sechs Monate später erinnert sich niemand mehr, welche Änderungen tragend sind und welche Reste von Experimenten waren, und niemand will derjenige sein, der die falsche Zeile entfernt.

Die leichteste mögliche Lösung: etckeeper

Für einen einzelnen Server ist der kleinste sinnvolle Schritt etckeeper, das /etc unter Git stellt und automatisch committet, wann immer der Paketmanager eine Config-Datei anfasst:

apt install etckeeper
cd /etc
git log --oneline -10

Von da an wird jede manuelle Änderung beim nächsten automatischen Commit von etckeeper erfasst (oder man committet direkt nach der Bearbeitung selbst mit git add -A && git commit). Der Nutzen zeigt sich beim ersten Mal, wenn nach einer Config-Änderung etwas kaputtgeht und man Folgendes ausführen kann:

git log -p -- nginx/sites-enabled/example.com

und genau sieht, was sich geändert hat, wann, und, wenn man eine Commit-Message geschrieben hat, warum. Genau das ist der entscheidende Unterschied: git commit -m "proxy_read_timeout für den langsamen Report-Export-Endpoint erhöht" ist der Unterschied zwischen "zukünftiges Ich versteht diese Config" und "zukünftiges Ich traut sich nicht, sie anzufassen".

Für mehrere Server: ein Configs-Repo pro Kunde

etckeeper ist lokal auf eine Maschine beschränkt, was für einen einzelnen VPS in Ordnung ist, aber nicht hilft, wenn ein Kunde drei oder vier Server mit zusammenhängenden Configs hat. Dafür halte ich ein separates Repo, strukturiert nach Host:

client-configs/
├── web-01/
│   ├── nginx/sites-available/example.com
│   └── fail2ban/jail.local
├── db-01/
│   ├── postgresql/postgresql.conf
│   └── pgbackrest/pgbackrest.conf
└── deploy.sh

Änderungen passieren lokal, werden vor dem Ausrollen als Diff geprüft, und ein kleines deploy.sh schiebt die relevanten Dateien auf den richtigen Host:

#!/bin/bash
HOST=$1
rsync -av "$HOST/" "deploy@$HOST.internal:/" --dry-run
# --dry-run entfernen, sobald der Diff stimmt

--dry-run als Standard ist Absicht. Config-Deploys sind genau die Art von Aufgabe, bei der ein falsch gesetzter Schrägstrich in rsync mehr überschreiben kann als beabsichtigt, deshalb zeigt das Standardverhalten erst, was sich ändern würde, bevor es tatsächlich passiert.

Was das bringt, was Dokumentation nicht bringt

Die übliche Alternative ist eine Wiki-Seite oder ein README mit "wichtigen Config-Änderungen". Diese veralten fast sofort, weil das Aktualisieren des Wikis ein separater Schritt von der eigentlichen Änderung ist, und separate Schritte werden unter Zeitdruck übersprungen. Git-Historie hat dieses Problem nicht, der Eintrag entsteht als Nebenprodukt der Arbeit, nicht als zusätzliche Aufgabe obendrauf.

Es verändert auch, wie Änderungen gemacht werden. Wenn eine Config in Git liegt, ist der naheliegende Weg, sie lokal zu bearbeiten, mit einer Begründung im Commit zu versehen und dann zu deployen, statt sich per SSH einzuloggen und die Live-Datei direkt zu bearbeiten. Genau aus dieser kleinen Verschiebung im Workflow kommt der größte Teil des Nutzens: nicht das Backup, sondern die Gewohnheit, kurz vor dem Was das Warum aufzuschreiben. Drei Monate später, wenn jemand (oft ich) vor einer Config sitzt und sich fragt, ob eine bestimmte Zeile gefahrlos entfernt werden kann, spart genau dieser eine Satz in einer Commit-Message eine Stunde vorsichtiger Archäologie.

VorherigerDas Ansible-Playbook, das auf jedem neuen Server läuftNächster Cron vs. systemd-Timer: Wann ich zu welchem greife