Gérer plusieurs machines NixOS
Lorsqu’on a plusieurs serveurs NixOS, il est pratique de centraliser les configurations dans un dépôt Git.
Structure recommandée
nixos-infra/
├── flake.nix
├── flake.lock
├── modules/
│ ├── base.nix # Configuration commune
│ ├── docker.nix # Module Docker réutilisable
│ └── monitoring.nix # Module monitoring
├── machines/
│ ├── web-01/
│ │ ├── configuration.nix
│ │ └── hardware-configuration.nix
│ ├── db-01/
│ │ ├── configuration.nix
│ │ └── hardware-configuration.nix
│ └── ...
└── secrets/ # Fichiers secrets (optionnel, avec agenix/sops)
Module de base partagé
modules/base.nix :
{ config, pkgs, ... }:
{
# Timezone et locale
time.timeZone = "Europe/Zurich";
i18n.defaultLocale = "en_US.UTF-8";
# Paquets communs
environment.systemPackages = with pkgs; [
git vim htop curl wget tmux
];
# SSH sécurisé
services.openssh.enable = true;
services.openssh.settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
# Firewall activé par défaut
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 22 ];
# Utilisateur admin
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAA... admin@workstation"
];
};
security.sudo.wheelNeedsPassword = false;
}
Configuration d’une machine
machines/web-01/configuration.nix :
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
../../modules/base.nix
];
networking.hostName = "web-01";
# Spécificités de cette machine
services.nginx.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
system.stateVersion = "24.05";
}
Flake pour multi-machines
flake.nix :
{
description = "Infrastructure NixOS";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
};
outputs = { self, nixpkgs }: {
nixosConfigurations = {
web-01 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./machines/web-01/configuration.nix ];
};
web-02 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./machines/web-02/configuration.nix ];
};
db-01 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./machines/db-01/configuration.nix ];
};
};
};
}
Déploiement
Depuis la machine locale
Sur chaque machine, cloner le repo et appliquer :
git clone https://github.com/monuser/nixos-infra.git /etc/nixos
cd /etc/nixos
sudo nixos-rebuild switch --flake .#web-01
Déploiement distant avec nixos-rebuild
Depuis sa workstation, déployer sur une machine distante :
nixos-rebuild switch --flake .#web-01 \
--target-host admin@web-01.example.com \
--use-remote-sudo
Déploiement avec deploy-rs
Pour un déploiement plus robuste, utiliser deploy-rs :
# Dans flake.nix
{
inputs.deploy-rs.url = "github:serokell/deploy-rs";
outputs = { self, nixpkgs, deploy-rs }: {
# ... nixosConfigurations ...
deploy.nodes = {
web-01 = {
hostname = "web-01.example.com";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos
self.nixosConfigurations.web-01;
};
};
};
};
}
Déployer :
nix run github:serokell/deploy-rs -- .#web-01
Workflow typique
- Modifier la configuration dans le repo Git
- Committer et pusher
- Sur la machine cible (ou à distance) :
cd /etc/nixos
git pull
sudo nixos-rebuild switch --flake .#$(hostname)
Automatisation avec CI/CD
Avec GitHub Actions, on peut vérifier que les configurations compilent :
name: Check NixOS configurations
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
experimental-features = nix-command flakes
- run: nix flake check