Text size
Ausprobiert & getestet6 Min. Lesezeit

"Arbeit auf meiner Maschine", mit Nix gelöst?

Wiederholbare Umgebungen für alle im Team.

"Works on my machine," solved with Nix?
KI-generierte Illustration

Jedes Team hat das Gespräch. "Der Build scheitert mir". "Funktioniert auf meiner Maschine". Dann zwanzig Minuten Vergleiche: verschiedene Terraform, ein neuerer Knoten, ein alter kubectl, ein Python, der mit macOS geliefert wurde, eine fehlende Systembibliothek.

Ein neues Teammitglied zu übernehmen, kann einen Tag dauern, nur um die richtigen Werkzeuge in den richtigen Versionen zu bekommen. Und CI benutzt oft eine ganz andere Version.

Reproduzierbare Entwicklungsumgebungen beheben das. Nix ist die mächtigste Möglichkeit, sie zu bekommen, und neuere Tools haben es viel zugänglicher gemacht.

Das Problem

Entwicklungsumgebungen werden durch folgende Faktoren verschoben:

  • Jeder installiert Tools anders: Homebrew, apt, heruntergeladene Binärdateien, Versionsmanager.
  • Versionen sind nicht festgehalten, oder in einem README, dem niemand folgt.
  • Werkzeuge hängen von Systembibliotheken ab, die sich zwischen Maschinen unterscheiden.
  • CI-Bilder werden getrennt von Entwickler-Setups aufbewahrt.

Was wir wollen: eine Datei im Repository, die genau definiert, welche Tools (und Versionen) das Projekt benötigt, die auf jeder Entwicklermaschine und in CI gleich funktioniert.

Nix in einem Absatz

Nix ist ein Paketmanager und Build-System, das auf einer radikalen Idee basiert: Jedes Paket wird isoliert von einer genauen Beschreibung seiner Eingaben erstellt und auf einem einzigartigen Pfad gespeichert, der auf einem Hash dieser Eingaben basiert (wie /nix/store/abc123-terraform-1.9.8) Mehrere Versionen leben ohne Konflikt nebeneinander. Nichts ist "global" installiert. Wenn zwei Maschinen dieselbe Nix-Beschreibung verwenden, erhalten sie genau die gleiche Software, Bit für Bit. Die Nixpkgs Die Sammlung enthält weit über 100.000 Pakete, eine der größten aller Paketmanager.

Nixflocken

Flakes sind die moderne Art, Nix-Projekte zu definieren, mit einer Schließdatei, die genaue Versionen von allem festlegt. Eine Entwicklungsshell für ein Infrastrukturprojekt:

{
  description = "Infrastructure dev environment";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

  outputs = { self, nixpkgs }:
    let
      systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
      forAll = f: nixpkgs.lib.genAttrs systems (s: f nixpkgs.legacyPackages.${s});
    in {
      devShells = forAll (pkgs: {
        default = pkgs.mkShell {
          packages = with pkgs; [
            opentofu
            kubectl
            kubernetes-helm
            awscli2
            jq
            shellcheck
          ];
        };
      });
    };
}

Lauf ! nix developUnd du bist in einer Hülle mit genau diesen Werkzeugen. Die flake.lock Die Datei verbindet sie, damit jeder die gleichen Versionen bekommt, bis jemand das Schloss absichtlich aktualisiert.

Ehrlich gesagt, Nix' Sprache und Konzepte haben eine steile Lernkurve. Da kommen freundlichere Werkzeuge ins Spiel.

Das Ziel ist nicht, Nix zu benutzen. Das Ziel ist, dass "die Werkzeuge installieren" zu einem Befehl wird, der immer das gleiche Ergebnis gibt.

Nix ohne Schmerzen

Der ist nicht gut. (von Jetify) verwendet Nix darunter, aber Sie schreiben nur eine einfache JSON-Datei:

{
  "packages": [
    "opentofu@1.10",
    "kubectl@1.33",
    "helm@latest",
    "awscli2@latest",
    "jq@latest"
  ],
  "shell": {
    "init_hook": ["echo 'Infra shell ready'"]
  }
}
devbox shell

Keine Nix-Wissen benötigt. Es kann auch Dockerfiles und Dev Container Konfigurationen aus derselben Datei generieren.

Abzug (von Cachix) ist eine weitere beliebte Option: mehr Nix unter der Haube, aber mit fertigen Modulen für Sprachen und Dienste (wie den Start einer lokalen PostgreSQL), Pre-Commit-Hooks und Skripts.

Beide funktionieren gut mit Rüben, die die Umgebung automatisch aktiviert , wenn Sie cd in den Projektordner.

Dev Container stattdessen?

Die Hauptalternative ist Entwicklungsbehälter: a devcontainer.json Das definiert ein Container-Image mit all Ihren Tools, die von VS Code, JetBrains IDE, GitHub Codespaces und anderen verwendet werden.

Nix / devbox / devenv Entwicklungsbehälter
Auslauf Nativ auf Ihrem Computer In einem Behälter
Reproduzierbarkeit Sehr hoch (verriegelte Eingänge) Kommt drauf an, wie das Bild aufgebaut ist.
Leistung auf macOS Native Geschwindigkeit Einige Kosten (Dateisystem, VM)
Lernkurve Steil (Nix), leicht (Devbox) Einfach , wenn du Docker kennst .
Integration des Editors Über Direnv, funktioniert überall. Ausgezeichnet in VS Code und Codespaces
Cloud-Entwicklungsumgebungen Möglich Native in Codespaces und ähnliches

Beides sind gute Entscheidungen. Entwickler Container sind den meisten Teams vertrauter. Nix-basierte Tools sind präziser und werden nativ ausgeführt. Einige Teams kombinieren sie sogar: Nix in einem Entwicklercontainer.

Nix in CI

Die wirkliche Auszahlung: gleiche Umgebung in CI Wie auf Laptops.

- uses: cachix/install-nix-action@<sha>
- run: nix develop --command make test

Oder mit devbox: devbox run test- Ich weiß . Ein binärer Cache (Cachix oder ein selbst gehosteter) hält CI schnell, indem er vorgefertigte Pakete herunterlädt, anstatt sie zu erstellen.

Keine "das CI-Bild hat eine andere Terraform-Version als mein Laptop".

Also, sollten Sie es versuchen?

Wenn Ihr Team regelmäßig Zeit verliert, weil Versionen nicht übereinstimmen und die Einbindung langsam ist, ja. Ich würde damit anfangen: Der ist nicht gut. in einem Repository: eine JSON-Datei, ein Befehl, keine Nix-Kenntnisse erforderlich. Wenn die Leute es mögen, dann gehen Sie tiefer mit Flocken oder Devenv. Wenn Ihr Team bereits in VS Code lebt, sind Dev Container ein ebenso guter Weg.

Meine Meinung: Die Werkzeuge Ihres Projekts sind Teil Ihres Projektes. Stecken Sie sie in das Repository, stecken Sie sie fest und stoppen Sie, sich gegenseitig die Laptops zu debuggen.

Desly