Clone-First: como anadir un MacBook M1 Max a un flake NixOS multi-maquina
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
- Compras el MacBook Pro M1 Max de segunda mano
- Desde macOS:
curl https://alx.sh | sh(instala UEFI, particiona) - Arrancas la ISO de nixos-apple-silicon desde USB
- Particionas, montas, generas
hardware-configuration.nix - Clonas dotfiles:
git clone https://github.com/tuusuario/dotfiles - Copias el
hardware-configuration.nixgenerado ahosts/macbook-m1/ sudo nixos-rebuild switch --flake ~/dotfiles#macbook-m1- 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:
- Kernel Asahi con todos los parches
- GPU con OpenGL 4.6, Vulkan 1.4, OpenCL 3.0 (certificados conformant)
- Audio completo: PipeWire + speakersafetyd + DSP calibrado por modelo
- WiFi, Bluetooth, webcam, microfonos, lector SD
- Suspend/sleep, control de brillo, retroiluminacion teclado
- cpufreq con
schedutilpara energy-aware scheduling - Mesa desde nixpkgs (soporte Asahi built-in desde 25.1+)
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.
Comentarios (0)
Sin comentarios todavia. Se el primero!
Deja un comentario