Arbeitet man eine Weile lang als Softwareentwickler, optimiert man seinen Workflow und seine Tools immer mehr. Die Optimierungen reichen von einfachen Editor-Shortcuts bis zu ganzen Shell-Scripten die z. B. als Git-Hook vor jedem Commit ausgeführt werden.

Wenn man auf mehr als einem Rechner arbeitet, so muss man diese Konfigurationen stets mehrfach pflegen. Dies kann sehr zeitaufwändig und fehleranfällig sein! Deshalb gibt es diverse Lösungen wie sich das synchronisieren der Konfiguration automatisieren lässt.

Diese Artikel beschreibt eine Lösung, die mit Hilfe von git und chezmoi oben genannte Probleme löst. Zudem bekommt man gratis eine Versionierung und ein Backup seiner aktuellen Konfiguration, sodass man im Falle von Problemen leicht frühere Versionen wieder herstellen kann.

Die meisten Programme speichern ihre Konfiguration heutzutage in Klartext-Dateien, sogenannten “dotfiles” 1. Diese Dateien findet man meist direkt im Homeverzeichnis des Nutzers (/home/$USER auf GNU/Linux bzw. %userprofile% auf Windows).

Ein naiver Ansatz

Um Klartext-Dateien zu verwalten, bietet es sich an diese in ein Git-Repository einzuchecken und über einen zentralen Git-Server (wie z. B. GitHub oder GitLab) an die einzelnen Rechner zu verteilen. Dadurch lassen sich die einzelnen Konfigurationsdateien mit den üblichen Mechanismen von Git auf mehreren Rechnern synchron halten. Zudem hat man eine Versionierung und eine Sicherungskopie auf dem Git-Server.

Die meisten Programme erwarten ihre Konfigurationsdateien Konfigurationsdateien an einem bestimmten Ort. Git auf der anderen Seite verwaltet alle Dateien in einem einzigen Verzeichnis. Man muss also irgendwie die Dateien aus dem Git-Verzeichnis an den Ort an dem sie die entsprechende Anwendung erwartet bringen. Ein naiver Ansatz wäre, diese Konfigurationsdateien mit Hilfe von hard-links an den korrekten Stellen zu verlinken.

Die Folgende Grafik zeigt diesen naiven Ansatz am Beispiel der Konfigurationsdatei ~/.bashrc:

Diagram, dass einen naiven Ansatz zeigt, bei dem die Konfigurationsdatein über hard-links in das GitRepository verlinkt werden.

Man würde zunächst ein neues git-repository unter dem Pfad ~/.dotfiles initialisieren (1) und die Konfigurationsdatei in diesem Repository anlegen (2). Damit Bash die Datei lesen kann, muss man einen Link auf diese Datei vom Pfad ~/.bashrc anlegen (3). Um diese Konfigurationsdatei auf einem zweiten Computer zur Verfügung zu stellen, fügt man sie dem Git-Repository hinzu (4) und pushed sie zum Git-Server (5).

Auf dem zweiten Computer cloned man das Repository (6) und verlinkt die Datei an die richtige Stelle (7). Hat sich etwas an der Datei geändert, kann man mit den üblichen Git-Mechanismen (4, 5, 8) die Konfiguration synchron halten.

Dieser Ansatz funktioniert grundsätzlich, hat aber ein paar Nachteile:

  • Das verlinken der Konfigurationsdateien (3, 7) muss für jede Datei auf jedem Rechner manuell getan werden.
  • Falls Computer 2 nicht exakt die gleiche Konfiguration haben soll, muss man selbst einen Mechanismus dafür programmieren.
  • Falls eine Konfiguration Geheimnisse (z. B. Passwörter oder API-Keys) enthält, so werden die auch dem Git-Repository hinzugefügt. Dies will man oft aus Sicherheitsgründen verhindern.

chezmoi

Um oben genannten Nachteilen zu begegnen bietet sich die Konfigurationsmanagement-Lösung chezmoi an. chezmoi setzt auf unserem naiven Ansatz auf, löst aber das Problem der Verknüpfung zwischen dem lokalen git-Repository dem erwarteten Ort der Konfigurationsdatei. chezmoi benutzt dabei keine Links sondern erstellt dabei eine Kopie der versionierten Datei. Es bietet ein komfortables Kommandozeileninterface um Änderungen anzuwenden und ggf. zu mergen. Darüber hinaus bietet es Möglichkeiten, um computerspezifische Konfigurationen und Geheimnisse zu verwalten.

Das oben genannte Beispiel würde mit chezmoi wie folgt aussehen:

Diagramm dass den Workflow mit chezmoi zeigt

Zunächst legt man sich ein neues Repository mit dem Kommando chezmoi initein (1). Anschließend fügt man die bestehende Konfigurationsdatei mit dem Kommando chezmoi add ~/.bashrchinzu. Dieses Kommando erstellt im chezmoi-Repository ~/.local/share/chezmoieine Kopie, die von chezmoi verwaltet wird (2). Um diese zu editieren verwendet man das Kommando chezmoi edit ~/.bashrc (3), dabei editiert man in Wirklichkeit die Datei ~/.local/share/chezmoi. Um die Änderung anzuwenden, führt man das Kommando chezmoi apply ~/.bashrcaus (4). Da diese beiden Kommandos oft zusammen benutzt werden, gibt es die Kurzform chezmoid edit --apply ..., dabei wird die Datei im chezmoi-Repository editiert und anschließend ein Apply ausgeführt. Um vor einem chezmoi applyzu sehen welche Änderungen vorgenommen werden gibt es das Kommando chezmoi diff (5).

Um die Änderungen nun auf einem zweiten Rechner zur Verfügung zu stellen benutzt man nahezu die gleiche Methode wie in unserem naiven Ansatz. chezmoi hat uns bereits ein lokales git-Repository erstellt mit dem wir über das Kommando chezmoi git interagieren können. Zunächst fügen wir die neuen Dateien dem lokalen git-Repository hinzu (6) und pushen sie anschließend zu unserem git-Server (7).

Auf dem zweiten Computer führen wir initialisieren wir ein neues chezmoi-Repository mit der URL zu unserem git-Server. Dadurch verknüpft chezmoi sein internes git-Repository automatisch mit dem git-Server. Das Flag --applywendet alle Konfigurationen zugleich an (8). Möchte man feingranularere Kontrolle, so lässt man das --apply⁻Flag weg und führt chezmoi apply nur für diese Dateien aus, die man von chezmoi verwaltet haben möchte (9). Um aktualisierte Konfigurationen zu bekommen führt man einen git-Pull (10) und ein anschließendes chezmoi apply aus (9). Alternativ gibt es das Kommando chezmoi updatedas pullund apply in einem Kommando verbindet (11).

Weitere Features

Im chezmoi apply Schritt erstellt die Konfigurationsdatei basierend auf der Datei im chezmoi-Repository. Im einfachsten Fall wird die Datei einfach kopiert. Es gibt aber auch die Möglichkeit Templates zu hinterlegen um maschinenspezifische Konfiguartionen zu hinterlegen, Skripte auszuführen oder Geheimnisse aus Passwortmanagern zu laden.

Um ein Template zu erstellen fügt man die Datei mit dem Flag --template hinzu, dies legt die Konfigurationsdatei mit dem Suffix .tmpl an. Um beispielweise die Editorvariable in der bashrcauf einem “work-pc” anders zu konfigurieren geht man wie folgt vor:

  1. Template der .bashrc anlegen: chezmoi add --template ~/.bashrc
  2. Template bearbeiten: chezmoi edit ~/.bashrc:
# ~/.local/share/chezmoi/dot_bashrc.tmpl

{{ if eq .chezmoi.hostname "work-laptop" }}
export EDITOR=nano
{{ else }}
export EDITOR=vim
{{ end }}

Der Templating-Mechanismus in chezmoi ist sehr mächtig, sodass dieser Artikel nur ein einfaches Beispiel zeigen kann. Für weiterführende Informationen siehe den chezmoi user guide

Fazit

chezmoi ist ein vielversprechendes Tool wenn es darum geht Konfigurationseinstellungen zu verwalten und zu synchronisieren. Trotzdem hat das Tool eine gewisse Lernkurve und erfordert eine gewisse Disziplin. Gerade bei grafischen Tools klickt man sich gerne seine Konfiguration zusammen und fertig. Um diese Einstellungen in chezmoi aufzunehmen muss man sie aber anschließend noch ins chezmoi-Repository übertragen. An diesen zusätzlichen Schritt muss man sich zunächst gewöhnen. Allerdings wird man damit belohnt, dass man jede Einstellung garantiert nur einmal vornehmen muss. Zudem hat man die Gewissheit, dass man die Konfiguration jederzeit wieder herstellen kann. Tauscht man beispielsweise einen Rechner aus, so reicht ein simples chezmoi init --aply <link-zu-git-repository>und alle Einstellungen sind wieder da.

Ich arbeite selbst seit einigen Monaten mit chezmoi und kann es wärmstens empfehlen. Derzeit synchronisiere ich nur meine Linux-Konfigurationen. Da chezmoi aber auch Support für Windows bietet, wäre es auch interessant zu schauen wie man Konfigurationen von Tools, die man sowohl auf Linux als auch auf Windows einsetzt synchron hält.


  1. Der Name dotfile kommt von der Unix-Konvention Konfigurationsdateien mit einem . als Prefix zu versehen wodurch sie als versteckte Dateien gelten. ↩︎