This commit is contained in:
2026-09-06 17:32:17 +02:00
commit e37e956f95
12 changed files with 956 additions and 0 deletions
+391
View File
@@ -0,0 +1,391 @@
# Nixos_Fleet
Déploiement en masse (PXE ou USB) du profil générique `usagers`.
Repo public. `git pull` sans mot de passe.
Ne contient aucune donnée des utilisateurs nommés. Ça, c'est dans [Nixos_Users](../nixos_users), repo privé séparé.
---
# Installer un PC
Une étape à la fois. Ne saute pas d'étape.
## Étape 1 — Brancher
Branche le câble réseau.
Branche le PC au secteur.
Allume le PC.
## Étape 2 — Menu de démarrage
Appuie plusieurs fois sur une touche dès l'allumage.
Dell → F12
HP → F9
Lenovo → F12
Choisis : Network Boot.
## Étape 3 — Attendre
Un écran noir avec du texte apparaît seul.
Attends.
## Étape 4 — Choisir un cas
Il y a deux cas. Choisis-en un seul.
PC normal → va à l'étape 4A.
PC pour thomas, clara, jade ou oreo → va à l'étape 4B.
## Étape 4A — PC normal
Tape : `1`
Appuie sur Entrée.
N'appuie plus sur rien.
Attends la fin (plusieurs minutes).
Va à l'étape 5.
## Étape 4B — PC pour une personne
Tape : `2`
Appuie sur Entrée.
Tape le prénom (thomas, clara, jade ou oreo).
Appuie sur Entrée.
Une question sur le chiffrement apparaît.
Pas sûr → appuie juste sur Entrée.
Tape le token (donné à part, pas dans ce guide).
Appuie sur Entrée.
Si une passphrase est demandée :
Tape-la.
Note-la sur papier tout de suite.
Attends la fin (plusieurs minutes).
Va à l'étape 5.
## Étape 5 — Redémarrage
Le PC redémarre seul.
N'y touche pas.
## Étape 6 — Connexion
PC normal :
Utilisateur : `usagers`
Mot de passe : `nixos`
PC pour une personne :
Utilisateur : le prénom tapé à l'étape 4B
Mot de passe : `nixos`
Un nouveau mot de passe est demandé tout de suite. Le choisir maintenant.
## Étape 7 — Vérifier
Le bureau s'affiche.
Firefox s'ouvre.
Le son fonctionne.
Tout est bon → le PC est prêt.
## Si ça bloque
N'insiste pas seul.
Préviens le référent technique.
---
# Installer le serveur PXE
Une étape à la fois.
## Étape 1 — Installer NixOS
ISO : https://nixos.org/download
Partitionnement normal.
Définir un mot de passe root.
## Étape 2 — Cloner le repo
```bash
nix-shell -p git
git clone https://gitea.miniclic.net/Damien/Nixos_Fleet.git /etc/nixos-fleet
cd /etc/nixos-fleet
```
## Étape 3 — Éditer 3 valeurs
Fichier : `pxe-server/configuration.nix`
`interface` → sortie de `ip a`
`serverIp` → IP fixe du serveur
`standaloneDhcp` → laisser `false` si le réseau a déjà un DHCP
```bash
$EDITOR pxe-server/configuration.nix
```
## Étape 4 — Construire
```bash
sudo nixos-rebuild switch --flake .#pxe-server
```
## Étape 5 — Publier l'image
```bash
sudo systemctl start pxe-publish
sudo systemctl status pxe-publish
```
Doit finir en "success". Première fois : plusieurs minutes.
## Étape 6 — Vérifier
```bash
sudo systemctl status dnsmasq caddy
ls /var/lib/tftpboot
ls /var/www/pxe
curl -I http://<serverIp>/netboot.ipxe
```
Tout doit répondre sans erreur.
## Étape 7 — Tester sur 1 PC
Démarrer un seul PC en PXE.
Vérifier qu'il arrive sur l'écran de choix.
Si le parc a du BIOS et de l'UEFI, tester les deux.
Ne pas lancer 20 PC avant que cette étape fonctionne.
## Après l'installation
Noter l'IP du serveur quelque part accessible à l'équipe.
Vérifier que `pxe-publish.timer` est actif :
```bash
systemctl is-enabled pxe-publish.timer
```
Ce serveur n'a rien à sauvegarder à part le repo git.
## Entretien
Republier l'image après une modif de `installer/` :
```bash
sudo systemctl start pxe-publish
```
Appliquer une modif de `pxe-server/configuration.nix` :
```bash
sudo nixos-rebuild switch --flake .#pxe-server
```
Voir les logs DHCP/TFTP :
```bash
journalctl -u dnsmasq -f
```
Voir les logs HTTP :
```bash
journalctl -u caddy -f
```
## Si ça bloque
Écran PXE ne trouve rien → revérifier `serverIp` et `interface`.
Boucle infinie au démarrage → regarder `journalctl -u dnsmasq` pendant un boot.
UEFI ou BIOS ne boote pas → vérifier les deux fichiers dans `/var/lib/tftpboot`.
IP qui changent tout le temps → un autre DHCP tourne déjà, repasser `standaloneDhcp` à `false`.
---
# Référence
## Contenu du repo
`hosts/usagers/` → le seul profil du repo. Jamais chiffré.
`disks/plain.nix` → layout disko (disque `main`, GPT+ESP+btrfs).
`installer/` → l'image d'installation, PXE et USB. Même image pour tous les cas.
`pxe-server/` → le serveur PXE (dnsmasq + Caddy).
## Pourquoi deux repos
Une machine de la flotte pull uniquement ce repo.
Les comptes thomas/clara/jade/oreo vivent dans un autre repo, privé.
La flotte ne voit jamais ce second repo.
## Graver la clé USB
```bash
nix build .#nixosConfigurations.installer-iso.config.system.build.isoImage
sudo dd if=result/iso/*.iso of=/dev/sdX bs=4M status=progress conv=fsync
```
Vérifier `/dev/sdX` avant de lancer `dd`.
## Mises à jour de la flotte
Chaque PC tire ses mises à jour directement depuis ce repo, tous les jours.
Pas de `git pull` manuel sur les PC. Juste `git push` ici.
## Avant la première vague de 100 PC
Rien de ce repo n'a été testé sur du vrai matériel.
À vérifier avant de lancer 100 PC :
Détection du disque, sur une machine à 2 disques internes.
Comportement du proxyDHCP, face au routeur réel.
Boot BIOS et boot UEFI, sur le parc réel.
Test sur 1-2 PC réels d'abord.
```bash
nix flake check
nix build .#nixosConfigurations.usagers.config.system.build.toplevel
nix build .#nixosConfigurations.installer-iso
```
---
# Travailler avec Git
## Cloner (première fois)
```bash
git clone https://gitea.miniclic.net/Damien/Nixos_Fleet.git
cd Nixos_Fleet
```
## Avant de modifier
```bash
git pull
```
Toujours, avant de commencer à éditer.
## Modifier et envoyer
```bash
git add -A
git commit -m "description courte"
git push
```
## Si le push est refusé
Quelqu'un a poussé avant toi.
```bash
git pull
```
Résoudre les conflits s'il y en a (voir plus bas).
Puis repousser :
```bash
git push
```
## Travailler à plusieurs
Un repo, plusieurs personnes : risque d'écraser le travail des autres.
Règle : une branche par changement.
```bash
git checkout -b mon-changement
```
Modifier. Commit. Push la branche :
```bash
git push -u origin mon-changement
```
Ouvrir une Pull Request sur Gitea.
Quelqu'un relit, merge depuis l'interface Gitea.
Jamais de push direct sur `main` à plusieurs.
## Si un conflit apparaît
Git l'annonce avec `CONFLICT` dans le message.
Ouvrir le(s) fichier(s) listé(s).
Chercher les marqueurs `<<<<<<<`, `=======`, `>>>>>>>`.
Choisir quelle version garder.
Supprimer les marqueurs.
```bash
git add <fichier>
git commit
git push
```
## Ce workflow git ne concerne que les développeurs
Les PC de la flotte ne font jamais `git pull`.
Ils tirent les mises à jour directement depuis l'URL git (voir plus haut).
+50
View File
@@ -0,0 +1,50 @@
# Layout disko pour les PC de la flotte : jamais chiffré (voir README).
# Le disque est déclaré sous le nom symbolique "main" ; le device réel est
# fourni au moment de l'install par : disko-install --disk main /dev/sdX
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/placeholder"; # remplacé par disko-install --disk main <device>
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/home" = {
mountpoint = "/home";
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
};
};
};
};
};
};
};
};
}
+40
View File
@@ -0,0 +1,40 @@
{
description = "Nixos_Fleet : parc de PC génériques (PXE/USB, disko, jamais chiffré)";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ self, nixpkgs, disko, ... }:
{
nixosConfigurations = {
usagers = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
disko.nixosModules.disko
./hosts/usagers/configuration.nix
];
};
installer-netboot = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./installer/netboot.nix ];
};
installer-iso = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./installer/iso.nix ];
};
pxe-server = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./pxe-server/configuration.nix ];
};
};
};
}
+23
View File
@@ -0,0 +1,23 @@
# Compte admin des machines de la flotte : root, mot de passe "nixos"
# STABLE (pas d'expiration forcée ici, contrairement à nixos_users) —
# ces machines sont génériques/partagées, un mot de passe connu et
# constant sur tout le parc est voulu pour l'administration courante.
{ pkgs, ... }:
{
users.mutableUsers = true;
users.users.root = {
initialPassword = "nixos";
};
# Login root direct autorisé nativement dès qu'un mot de passe est
# défini (console/tty). SSH reste sur le défaut NixOS (clé uniquement) :
# le mot de passe "nixos" n'ouvre pas la porte à distance, seulement en
# local sur la machine.
# `initialPassword` n'est appliqué par NixOS qu'à la création du compte,
# donc un rebuild/auto-upgrade ultérieur ne le réécrit jamais — mais ici
# on ne force pas non plus de changement : "nixos" doit rester valide
# indéfiniment sur la flotte.
}
+68
View File
@@ -0,0 +1,68 @@
# Socle commun à toutes les machines de la flotte (repo public).
{ pkgs, ... }:
{
# Toutes les machines de la flotte portent le même nom : pas
# d'identification individuelle pour l'instant (voir README du repo
# racine). À revoir plus tard via le numéro de série DMI si un vrai
# besoin d'identification apparaît.
networking.hostName = "Nixos_Fleet";
networking.networkmanager.enable = true;
time.timeZone = "Europe/Paris";
i18n.defaultLocale = "fr_FR.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "fr_FR.UTF-8";
LC_IDENTIFICATION = "fr_FR.UTF-8";
LC_MEASUREMENT = "fr_FR.UTF-8";
LC_MONETARY = "fr_FR.UTF-8";
LC_NAME = "fr_FR.UTF-8";
LC_NUMERIC = "fr_FR.UTF-8";
LC_PAPER = "fr_FR.UTF-8";
LC_TELEPHONE = "fr_FR.UTF-8";
LC_TIME = "fr_FR.UTF-8";
};
services.xserver.xkb = {
layout = "fr";
variant = "";
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.configurationLimit = 10;
services.openssh.enable = true;
networking.firewall.enable = true;
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true;
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
# Convergence : chaque machine de la flotte tire ses mises à jour du
# même repo public, sans intervention humaine (pas de netrc nécessaire
# ici, contrairement au repo nixos_users). Voir README pour adapter
# l'URL réelle du repo.
system.autoUpgrade = {
enable = true;
dates = "daily";
flake = "git+https://gitea.miniclic.net/Damien/Nixos_Fleet.git#usagers";
};
environment.systemPackages = with pkgs; [
git
curl
wget
htop
nixfmt
];
system.stateVersion = "26.05";
}
+57
View File
@@ -0,0 +1,57 @@
# Bureau Cinnamon générique pour la flotte. Adapté (pas importé) depuis
# nixos_cinnamon/hosts/cinnamon/desktop-cinnamon.nix : les deux repos
# restent indépendants au `git pull`.
{ pkgs, ... }:
{
services.xserver.enable = true;
services.xserver.displayManager.lightdm.enable = true;
services.xserver.desktopManager.cinnamon.enable = true;
services.accounts-daemon.enable = true;
environment.cinnamon.excludePackages = with pkgs; [
celluloid
warpinator
];
# Réglages de confidentialité génériques (pas de SearXNG/DNS personnels
# comme sur le poste perso — cette config est destinée à être publique).
programs.firefox = {
enable = true;
languagePacks = [ "fr" ];
preferences = {
"privacy.resistFingerprinting" = true;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.search.suggest.enabled" = false;
"dom.security.https_only_mode" = true;
"media.peerconnection.enabled" = false;
"geo.enabled" = false;
"network.captive-portal-service.enabled" = false;
};
policies = {
DisableTelemetry = true;
DisablePocket = true;
DisableFirefoxStudies = true;
OfferToSaveLogins = false;
DontCheckDefaultBrowser = true;
EnableTrackingProtection = {
Value = true;
Locked = true;
};
ExtensionSettings = {
"uBlock0@raymondhill.net" = {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
installation_mode = "force_installed";
};
};
};
};
environment.systemPackages = with pkgs; [
libreoffice
thunderbird
vlc
];
}
+20
View File
@@ -0,0 +1,20 @@
# Profil générique "usagers" : poste non-nominatif de la flotte.
{ ... }:
{
imports = [
../common/base.nix
../common/accounts.nix
../common/desktop.nix
../../disks/plain.nix
];
# Compte de session non-nominatif, mot de passe "nixos" stable, sans
# expiration forcée (voir hosts/common/accounts.nix).
users.users.usagers = {
isNormalUser = true;
description = "Usagers";
extraGroups = [ "networkmanager" ];
initialPassword = "nixos";
};
}
+115
View File
@@ -0,0 +1,115 @@
# Pas de shebang ici : ce fichier est injecté comme corps de script par
# pkgs.writeShellScriptBin dans installer-base.nix (qui ajoute déjà
# `#!...` + `set -euo pipefail`).
#
# Installeur unique pour les deux repos :
# - branche "flotte" -> nixos_fleet (public, jamais chiffré)
# - branche "utilisateur nommé" -> nixos_users (privé, chiffrement au choix)
# Ce script ne contient aucun secret : le token du repo privé est saisi en
# direct, jamais stocké dans ce fichier ni dans un repo git.
FLEET_REPO="git+https://gitea.miniclic.net/Damien/Nixos_Fleet.git"
USERS_REPO_HOST="gitea.miniclic.net"
USERS_REPO_PATH="Damien/Nixos_Users.git"
echo "=== Installeur Nixos_Fleet ==="
echo "1) PC de la flotte (générique)"
echo "2) Poste utilisateur nommé"
read -rp "Choix [1/2] : " CHOICE
# --- Détection automatique du disque cible -------------------------------
# On exclut les disques amovibles (la clé USB de boot elle-même) et les
# loop/rom. S'il en reste plusieurs (rare), on prend le plus gros et on le
# signale clairement dans les logs plutôt que de bloquer sur un menu.
echo
echo "Détection du disque cible..."
mapfile -t CANDIDATES < <(
lsblk -dn -b -o NAME,TYPE,RM,SIZE |
awk '$2 == "disk" && $3 == 0 { print $4, $1 }' |
sort -rn
)
if [ "${#CANDIDATES[@]}" -eq 0 ]; then
echo "Aucun disque fixe détecté. Abandon." >&2
exec bash
fi
DEVICE="/dev/$(echo "${CANDIDATES[0]}" | awk '{print $2}')"
if [ "${#CANDIDATES[@]}" -gt 1 ]; then
echo "ATTENTION : plusieurs disques fixes détectés, le plus gros a été retenu : $DEVICE"
printf ' %s\n' "${CANDIDATES[@]}"
else
echo "Disque retenu : $DEVICE"
fi
case "$CHOICE" in
1)
# --- Branche flotte : rien d'autre à saisir -----------------------
echo
echo "Installation du profil générique 'usagers' sur $DEVICE..."
nix run 'github:nix-community/disko#disko-install' -- --write-efi-boot-entries \
--flake "${FLEET_REPO}#usagers" \
--disk main "$DEVICE"
;;
2)
# --- Branche utilisateur nommé -------------------------------------
read -rp "Utilisateur (thomas/clara/jade/oreo) : " USER_PROFILE
USER_PROFILE=$(echo "$USER_PROFILE" | tr '[:upper:]' '[:lower:]' | xargs)
case "$USER_PROFILE" in
thomas|clara|jade|oreo) ;;
*)
echo "Utilisateur inconnu : $USER_PROFILE" >&2
exec bash
;;
esac
read -rp "Chiffrer le disque ? [o/N] : " ENCRYPT
ATTR="$USER_PROFILE"
if [[ "$ENCRYPT" =~ ^[oOyY] ]]; then
ATTR="${USER_PROFILE}-luks"
fi
read -rsp "Token Gitea (repo privé Nixos_Users) : " TOKEN
echo
# Le token n'est utilisé qu'en mémoire/ligne de commande pour ce fetch
# ponctuel : il n'est jamais écrit dans un fichier suivi par git.
AUTHED_URL="git+https://${TOKEN}@${USERS_REPO_HOST}/${USERS_REPO_PATH}"
echo
echo "Installation du profil '$ATTR' sur $DEVICE..."
if [[ "$ATTR" == *-luks ]]; then
echo "Disque chiffré : disko va demander une passphrase LUKS pendant le partitionnement."
fi
nix run 'github:nix-community/disko#disko-install' -- --write-efi-boot-entries \
--flake "${AUTHED_URL}#${ATTR}" \
--disk main "$DEVICE"
# Le système installé doit pouvoir continuer à tirer ses mises à jour
# du repo privé tout seul : on lui laisse un netrc, jamais commité,
# jamais dans le Nix store (nix.settings.netrc-file dans le repo
# nixos_users pointe vers ce même chemin).
#
# ATTENTION : le format exact attendu par Gitea (login=token vs
# login+password séparés) dépend de la version/config du serveur —
# à vérifier sur l'instance réelle avant le déploiement pilote.
mkdir -p /mnt/etc/nix
{
echo "machine ${USERS_REPO_HOST}"
echo "login ${TOKEN}"
echo "password x-oauth-basic"
} > /mnt/etc/nix/netrc
chmod 600 /mnt/etc/nix/netrc
;;
*)
echo "Choix invalide." >&2
exec bash
;;
esac
echo
echo "Installation terminée. Redémarrage dans 10s (Ctrl-C pour annuler et inspecter /mnt)..."
sleep 10
reboot
+48
View File
@@ -0,0 +1,48 @@
# Environnement live commun aux deux formes d'image (PXE netboot / ISO
# USB). Contient juste de quoi partitionner et lancer disko-install ; la
# vraie configuration cible est toujours récupérée depuis git au moment
# de l'install (repo public nixos_fleet ou repo privé nixos_users).
{ pkgs, lib, ... }:
let
installScript = pkgs.writeShellScriptBin "fleet-install" (builtins.readFile ./install.sh);
in
{
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
environment.systemPackages = with pkgs; [
git
parted
gptfdisk
util-linux # lsblk
installScript
];
# disko-install n'est pas préinstallé : install.sh l'invoque via
# `nix run github:nix-community/disko#disko-install`, ce qui évite de
# dépendre d'un nom de paquet nixpkgs précis (pas de package `disko`
# garanti tel quel côté nixpkgs) et reste conforme à l'usage documenté
# du projet.
networking.networkmanager.enable = true;
services.xserver.xkb.layout = "fr";
console.keyMap = "fr";
# Root autologin sur tty1, l'installeur se lance automatiquement au
# login. S'il échoue ou qu'on le quitte, on retombe sur un shell root
# normal pour dépanner à la main — pas de piège sans issue.
services.getty.autologinUser = "root";
users.users.root.password = lib.mkForce "";
environment.etc."profile.d/00-fleet-installer.sh".text = ''
if [ "$(tty)" = "/dev/tty1" ] && [ -z "$FLEET_INSTALLER_RAN" ]; then
export FLEET_INSTALLER_RAN=1
${installScript}/bin/fleet-install
fi
'';
system.stateVersion = "26.05";
}
+9
View File
@@ -0,0 +1,9 @@
# Image ISO bootable sur clé USB, en secours du PXE (même install.sh).
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")
./installer-base.nix
];
}
+9
View File
@@ -0,0 +1,9 @@
# Image PXE (kernel + initrd + squashfs), servie par pxe-server/.
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/netboot/netboot-minimal.nix")
./installer-base.nix
];
}
+126
View File
@@ -0,0 +1,126 @@
# Serveur PXE déclaratif : DHCP-proxy (ou DHCP complet)+TFTP (dnsmasq)
# pour le premier étage iPXE, HTTP (Caddy) pour kernel/initrd/script iPXE
# (TFTP seul est trop lent pour de gros fichiers). Ce host n'a besoin
# d'aucune donnée privée : il ne sert que l'image d'installation publique
# nixos_fleet ; le repo privé nixos_users n'est fetché qu'au moment de
# l'install, directement par la machine en cours d'installation.
{ config, lib, pkgs, ... }:
let
# true = ce serveur devient l'UNIQUE serveur DHCP du réseau cible.
# false = proxyDHCP uniquement : coexiste avec le routeur/DHCP existant,
# répond seulement aux requêtes de boot PXE. C'est le mode
# recommandé si les 100 PC restent sur un réseau qui a déjà un
# DHCP (le cas le plus probable).
standaloneDhcp = false;
# À adapter à l'interface réseau réelle du serveur, et à son IP fixe
# (le script iPXE doit pointer vers une adresse stable, pas un nom
# d'interface).
interface = "eth0";
serverIp = "192.168.1.10";
fleetRepo = "git+https://gitea.miniclic.net/Damien/Nixos_Fleet.git";
webroot = "/var/www/pxe";
tftpRoot = "/var/lib/tftpboot";
in
{
networking.hostName = "pxe-server";
networking.firewall.allowedUDPPorts = [
67
69
4011
];
networking.firewall.allowedTCPPorts = [ 80 ];
services.dnsmasq = {
enable = true;
settings = {
port = 0; # pas de résolution DNS, uniquement DHCP/TFTP/PXE
inherit interface;
"enable-tftp" = true;
"tftp-root" = tftpRoot;
# Détection d'architecture + évite la boucle de chainload iPXE :
# une machine qui a déjà démarré en iPXE s'annonce via l'option 175,
# on lui sert alors le script HTTP plutôt que de rechainer le même
# binaire à l'infini.
"dhcp-match" = [
"set:ipxe,175"
"set:efi-x86_64,option:client-arch,7"
];
"dhcp-boot" = [
"tag:ipxe,http://${serverIp}/netboot.ipxe"
"tag:!ipxe,tag:efi-x86_64,ipxe.efi"
"tag:!ipxe,tag:!efi-x86_64,undionly.kpxe"
];
}
// (
if standaloneDhcp then
{ "dhcp-range" = [ "192.168.1.50,192.168.1.150,12h" ]; } # à adapter au réseau cible
else
{ "dhcp-range" = [ "192.168.1.0,proxy" ]; } # à adapter au sous-réseau existant
);
};
# `:80` explicite (pas de nom de domaine) : Caddy ne tente donc aucune
# demande de certificat ACME, il sert juste du HTTP nu en local — exactement
# ce qu'il faut pour du netboot sur un LAN.
services.caddy = {
enable = true;
virtualHosts.":80" = {
extraConfig = ''
root * ${webroot}
file_server
'';
};
};
systemd.tmpfiles.rules = [
"d ${tftpRoot} 0755 dnsmasq dnsmasq -"
"d ${webroot} 0755 caddy caddy -"
];
# Republie l'image d'installation netboot depuis le repo public. À
# relancer après chaque évolution notable de installer/ dans
# nixos_fleet (systemctl start pxe-publish), en plus du rafraîchissement
# quotidien automatique ci-dessous.
systemd.services.pxe-publish = {
description = "Publie l'image d'installation netboot Nixos_Fleet pour le PXE";
path = [ config.nix.package ];
script = ''
set -euo pipefail
kernel=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.kernel")
initrd=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.netbootRamdisk")
ipxeScript=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.netbootIpxeScript")
install -m 0644 "$kernel/bzImage" "${webroot}/bzImage"
install -m 0644 "$initrd/initrd" "${webroot}/initrd"
install -m 0644 "$ipxeScript/netboot.ipxe" "${webroot}/netboot.ipxe"
# Binaires iPXE premier étage (BIOS + UEFI). Noms de sortie du
# paquet pkgs.ipxe à vérifier sur la version réelle avant le pilote.
install -m 0644 "${pkgs.ipxe}/undionly.kpxe" "${tftpRoot}/undionly.kpxe" || true
install -m 0644 "${pkgs.ipxe}/ipxe.efi" "${tftpRoot}/ipxe.efi" || true
'';
serviceConfig.Type = "oneshot";
};
systemd.timers.pxe-publish = {
description = "Rafraîchit quotidiennement l'image PXE (converge avec nixos_fleet)";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
};
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
networking.networkmanager.enable = lib.mkDefault true;
services.openssh.enable = true;
system.stateVersion = "26.05";
}