Clone-First: como anadir un MacBook M1 Max a un flake NixOS multi-maquina


23 de febrero de 2026

Ayer publique una guia generica de NixOS en M1 Max. Hoy va la version real: como lo vamos a hacer nosotros con un flake multi-maquina que ya gestiona 3 hosts + un Android.

La gracia no es instalar NixOS. Es que compras un portatil, clonas un repo, ejecutas un comando, y tienes tu entorno completo. Mismo Emacs, mismo fish, mismo XMonad, mismos scripts. En un hardware completamente distinto.

La arquitectura: clone-first

La idea es simple. Todas las maquinas son clones identicos. Solo cambia el hardware.

dotfiles/
  flake.nix                      # Entry point
  modules/base/                  # Comun a TODAS las maquinas
  modules/home-manager/          # Config de usuario (emacs, fish, alacritty...)
  hardware/                      # Modulos hardware especificos
  hosts/<hostname>/              # Solo overrides y hardware-configuration.nix

El corazon es una funcion mkSystem en el flake.nix que construye cualquier maquina:

mkSystem = { hostname, hardware ? [], extra ? [] }:
  nixpkgs.lib.nixosSystem {
    inherit system;
    modules = [
      ./modules/base              # Base identica
      ./hosts/${hostname}/hardware-configuration.nix
      ./hosts/${hostname}         # Overrides locales
      { networking.hostName = hostname; }
      # + home-manager, nix-index, etc.
    ] ++ hardware ++ extra;
  };

Y cada maquina es una llamada:

aurin = mkSystem {
  hostname = "aurin";
  hardware = [ ./hardware/nvidia/rtx2060.nix ./hardware/audio/fiio-k7.nix ];
};

vespino = mkSystem {
  hostname = "vespino";
  hardware = [];  # headless, sin GPU
};

macbook = mkSystem {
  hostname = "macbook";
  hardware = [
    nixos-hardware.nixosModules.apple-macbook-pro
    ./hardware/apple/macbook-pro-13-2.nix
  ];
};

Tres maquinas. Un flake. Misma base. Cuando modificas modules/base/desktop.nix, las tres maquinas lo reciben. Cuando modificas hardware/nvidia/rtx2060.nix, solo aurin lo ve.

El problema: aarch64-linux

Aqui es donde se pone interesante. El flake actual hardcodea:

system = "x86_64-linux";

El M1 Max es aarch64-linux. No puedes mezclar arquitecturas en el mismo nixpkgs.lib.nixosSystem. Esto es un fork real en la arquitectura del flake.

La solucion es parametrizar mkSystem:

mkSystem = {
  hostname,
  hardware ? [],
  extra ? [],
  system ? "x86_64-linux",  # <-- nuevo parametro con default
}:
let
  pkgs = import nixpkgs {
    inherit system;
    config.allowUnfree = true;
  };
in
nixpkgs.lib.nixosSystem {
  inherit system;
  specialArgs = { inherit inputs pkgs; };
  modules = [
    ./modules/base
    ./hosts/${hostname}/hardware-configuration.nix
    ./hosts/${hostname}
    { networking.hostName = hostname; }
  ] ++ hardware ++ extra;
};

Un parametro. Eso es todo lo que separa x8664 de aarch64 en la funcion. El default sigue siendo x86_64-linux para no romper las maquinas existentes.

El nuevo input: nixos-apple-silicon

En la seccion de inputs del flake, anadimos:

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

  nixos-apple-silicon = {
    url = "github:nix-community/nixos-apple-silicon";
    # NO usar inputs.nixpkgs.follows -- rompe el cache binario de Cachix
  };
};

Detalle critico: si haces inputs.nixpkgs.follows = "nixpkgs" pierdes el cache binario porque los hashes cambian. Compilar el kernel Asahi desde cero lleva bastante rato. Con el cache de Cachix, es un download.

La nueva maquina: una llamada

macbook-m1 = mkSystem {
  hostname = "macbook-m1";
  system = "aarch64-linux";  # <-- la unica diferencia real
  hardware = [
    nixos-apple-silicon.nixosModules.apple-silicon-support
    ./hardware/apple/macbook-pro-m1-max.nix
  ];
};

Eso es todo. Una llamada a mkSystem con system = "aarch64-linux" y el modulo de Apple Silicon. El resto – base, home-manager, fish, emacs, alacritty – viene gratis.

El modulo hardware

hardware/apple/macbook-pro-m1-max.nix es donde van las cosas especificas del M1 Max:

{ config, pkgs, lib, ... }:
{
  # U-Boot NO soporta EFI variables
  boot.loader.efi.canTouchEfiVariables = lib.mkForce false;

  # Firmware WiFi extraido de macOS
  hardware.asahi.peripheralFirmwareDirectory = ./firmware;

  # WiFi -- iwd, NO wpa_supplicant (WPA3 + Broadcom = roto)
  networking.wireless.iwd = {
    enable = true;
    settings.General.EnableNetworkConfiguration = true;
  };

  # Cache binario Asahi (evita compilar kernel)
  nix.settings = {
    extra-substituters = [ "https://nixos-apple-silicon.cachix.org" ];
    extra-trusted-public-keys = [
      "nixos-apple-silicon.cachix.org-1:..."
    ];
  };

  # Fix layout teclado
  boot.extraModprobeConfig = ''
    options hid_apple iso_layout=0
  '';
}

Comparalo con el modulo del MacBook Intel actual (hardware/apple/macbook-pro-13-2.nix): diferente hardware, misma filosofia. Un fichero .nix que encapsula todo lo que ese hardware necesita. Lo enchufas al flake, la base se encarga del resto.

El workflow real: de caja a escritorio

  1. Compras el MacBook Pro M1 Max de segunda mano
  2. Desde macOS: curl https://alx.sh | sh (instala UEFI, particiona)
  3. Arrancas la ISO de nixos-apple-silicon desde USB
  4. Particionas, montas, generas hardware-configuration.nix
  5. Clonas dotfiles: git clone https://github.com/tuusuario/dotfiles
  6. Copias el hardware-configuration.nix generado a hosts/macbook-m1/
  7. sudo nixos-rebuild switch --flake ~/dotfiles#macbook-m1
  8. Reinicio. Tu escritorio completo esta ahi.

Paso 7 es donde la magia ocurre. NixOS descarga todo lo que necesita, configura el sistema declarativamente, instala home-manager con tu dotconfig completa. No hay "ahora instala emacs, ahora configura fish, ahora…" No. Todo de golpe.

Lo que el modulo de Apple Silicon te regala

No hace falta configurar nada de esto – el modulo de nixos-apple-silicon lo hace automaticamente:

Lo unico que NO funciona todavia: Thunderbolt/DP Alt Mode (monitores externos solo via HDMI) y TouchID.

La diferencia respecto a "instalar NixOS en un portatil"

Cualquiera puede instalar NixOS en un portatil. Lo que cambia con clone-first es que no estas instalando un sistema – estas desplegando una configuracion que ya existe y funciona.

Si manana se rompe el MacBook, compras otro, clonas, rebuild, y tienes exactamente lo mismo. Si quieres probar algo peligroso, lo haces en la maquina de test. Si funciona alli, funciona en todas.

Esto es lo que NixOS promete y que la mayoria de la gente no implementa: reproducibilidad real entre maquinas heterogeneas. Un dual Xeon con NVIDIA, un servidor headless, un MacBook Intel, un MacBook Apple Silicon, y un movil Android. Mismo flake. Mismo usuario. Mismo entorno.

sudo nixos-rebuild switch --flake ~/dotfiles#macbook-m1

Un comando. Tu escritorio completo. En hardware que hace dos anos no corria Linux.

Eso es clone-first.

Comparte este post:

Es tu post

Estas seguro? Esto no se puede deshacer.

Comentarios (0)

Sin comentarios todavia. Se el primero!

Deja un comentario