muscari: add NixOS host config adapted from nix-config-legacy

Migrated muscari from nix-config-legacy (preserved for reference per
garden.md) to new multi-host flake structure.

Includes:
- hosts/muscari/default.nix: hostname, GRUB (BIOS), firewall
  (22/80/443), SSH keys via forgejo .keys endpoint with sha256 pinning,
  stateVersion 25.11
- hosts/muscari/disk-config.nix: disko config — 512M ESP + ext4 root,
  device = /dev/vda (YC standard-v3 single virtio disk)
- hosts/muscari/k3s.nix: k3s single-node with --flannel-backend=none
  (Cilium to be installed separately via Helm)

Architecture decisions (unchanged from legacy):
- Bootloader: GRUB (VM is in Legacy BIOS mode — see PREREQUISITES.md
  check 5+11 in projects/servers/muscari/)
- Filesystem: ext4 root + vfat ESP (ESP unused in BIOS but ready if
  ever switched to UEFI)
- Build deps: nixpkgs/nixos-25.11

Verification (after commit):
- nix flake show: nixosConfigurations.{muscari,rosemary} OK
- muscari.networking.hostName = "muscari"
- muscari.boot.loader.grub.enable = true
- muscari.boot.loader.systemd-boot.enable = false
- muscari.services.k3s.enable = true
- fileSystems derived correctly from disko
- poppy (darwin) and rosemary (NixOS) configs untouched

Session: verify plan
This commit is contained in:
mikl 2026-06-27 03:14:16 +03:00
parent c95e4a1488
commit 1f960a53a5
4 changed files with 238 additions and 4 deletions

111
flake.lock Normal file
View file

@ -0,0 +1,111 @@
{
"nodes": {
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1781152676,
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"owner": "nix-community",
"repo": "disko",
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1782423922,
"narHash": "sha256-qPNd6lUohHP5gcJhqQ7rLV87RwIx0xYR2A4Frb9Zjc4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "5d320ab301cfaaca7d32514f13815d19d109f5f4",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1781761792,
"narHash": "sha256-rCPytmKNjctLloB6UgK5CRrHSwV4b0ygxtJLPPp8R14=",
"owner": "LnL7",
"repo": "nix-darwin",
"rev": "a1fa429e945becaf60468600daf649be4ba0350c",
"type": "github"
},
"original": {
"owner": "LnL7",
"repo": "nix-darwin",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1782335603,
"narHash": "sha256-sZkQH1CkiZtdvcaLx4sGQD9Q9h+A8qB04DRpqQCN530=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "03c72920da828594fae523aaef96f33dff10b340",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"disko": "disko",
"home-manager": "home-manager",
"nix-darwin": "nix-darwin",
"nixpkgs": "nixpkgs",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1782165805,
"narHash": "sha256-478kKQBvK6SYTOdN2h9jhKJv94nbXRbFMfuL1WshErg=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "56b24064fdcaedca53553b1a6d607fd23b613a24",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,6 +1,49 @@
{ ... }:
{
networking.hostName = "muscari";
# muscari — k3s single-node cluster на YC (Debian 12 → NixOS 25.11 через nixos-install в tmux)
# https://git.iscg.dev/mikl/nix-config
#
# Этот host перенесён из nix-config-legacy (см. commits в legacy repo).
# VM: 158.160.166.30, 2 vCPU / 8 GB / 64 GB SSD (network-ssd), Legacy BIOS
# TODO: migrate from nix-config-legacy/hosts/muscari
{ config, pkgs, lib, ... }:
{
imports = [
./disk-config.nix
./k3s.nix
];
networking = {
hostName = "muscari";
useDHCP = true;
firewall.allowedTCPPorts = [
22 # SSH
80 # HTTP (Ingress через Traefik)
443 # HTTPS (Ingress через Traefik)
# 6443 не открываем — kubectl через SSH-туннель
];
};
# Bootloader — GRUB (Legacy BIOS mode, см. PREREQUISITES.md check 5+11)
boot.loader.grub = {
enable = true;
device = "/dev/vda";
useOSProber = false;
};
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.loader.efi.canTouchEfiVariables = lib.mkForce false;
# SSH ключи для mikl: forgejo .keys endpoint с sha256-pinning
# + hardcoded fallback ключ для восстановления
users.users.mikl.openssh.authorizedKeys.keyFiles = [
(pkgs.fetchurl {
url = "https://git.iscg.dev/mikl.keys";
sha256 = "sha256-4n6QLUPozdhHOmsRCuFn7HR9BU3nF0/GR2E7s5Lpz+Q=";
})
];
# fileSystems — определяется через disko (см. disk-config.nix)
# Не задаём явно fileSystems."/" чтобы не конфликтовать с disko
# После nixos-install первая установка 25.11,
# потом не трогаем (NixOS convention)
system.stateVersion = "25.11";
}

View file

@ -0,0 +1,44 @@
# disk-config.nix для muscari — Yandex Cloud VM
# YC VM из образа Debian 12: один диск /dev/vda (virtio scsi), GPT
# Используем disko для переформатирования под NixOS:
# - 512M ESP (vfat) для /boot — не используется в BIOS mode (GRUB ставит в MBR),
# но если когда-нибудь переключимся на UEFI, раздел будет готов
# - остальное → ext4 root
#
# Bootloader: GRUB (BIOS mode, см. hosts/muscari/default.nix)
#
# Перенесено из nix-config-legacy (commit 231f9d5 — диск-фикс для disko 1.13+)
{ lib, ... }:
{
disko.devices = {
disk.disk1 = {
device = lib.mkDefault "/dev/vda";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%"; # disko 1.13+ требует "100%" вместо "100%FREE"
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
}

36
hosts/muscari/k3s.nix Normal file
View file

@ -0,0 +1,36 @@
# k3s daemon для muscari (single-node + Cilium CNI)
# Traefik и servicelb остаются включены (встроенные в k3s)
# Cilium ставится отдельно через Helm после старта k3s
{ config, pkgs, lib, ... }:
{
services.k3s = {
enable = true;
extraFlags = [
# CNI: отключаем встроенный flannel, ставим Cilium отдельно
"--flannel-backend=none"
"--disable-network-policy" # Cilium сам делает network policy
# CIDR для подов и сервисов (default для k3s, но фиксируем явно)
"--cluster-cidr=10.42.0.0/16"
"--service-cidr=10.43.0.0/16"
# TLS SANs для kubectl (если подключаемся не только по IP)
"--tls-san=muscari.iscg.dev"
];
};
# Firewall: доверяем Cilium veth интерфейсам
networking.firewall = {
trustedInterfaces = [ "cali+" ];
checkReversePath = lib.mkDefault "loose";
};
# k3s-specific пакеты (НЕ в common — только для хостов с k3s)
environment.systemPackages = with pkgs; [
kubectl
kubernetes-helm
kustomize
sops # для шифрования k8s secrets (если будем через SOPS)
];
}