Ты ставишь цель: “хочу, чтобы на моём ноуте/сервере были Docker, Nginx, PostgreSQL, открыты нужные порты, создан пользователь с ключом, и всё это работало одинаково каждый раз”. В Debian/Arch/macOS ты делаешь это руками: ставишь пакеты, правишь конфиги, включаешь сервисы, добавляешь себя в группы, настраиваешь файрвол. Через месяц забываешь, что именно делал, и на новой машине всё повторяется с нуля.
В NixOS ты один раз описываешь желаемое состояние в файле. Потом выполняешь один rebuild. Всё. Система сама приводит себя к этому состоянию: установит пакеты, включит сервисы, создаст пользователя, откроет порты, разложит конфиги — без твоих ручных команд. Если что-то пошло не так — откат за один шаг.
- Почему так проще
- Декларативность: один файл — один источник правды о системе.
- Воспроизводимость: пиннинг каналов через flakes, одинаковые версии везде.
- Атомарные обновления и откаты: генерации системы переключаются без “полупочинки”.
- Нет конфигурационного дрейфа: не надо помнить, что ты делал руками.
- Масштабирование: этот же файл подходит и для нового ноутбука, и для 10 серверов.
- Контраст с Debian/Arch/macOS
- Императивные шаги: apt/pacman/brew, systemctl enable, usermod, ручные правки /etc.
- Откаты сложны: снапшоты, бэкапы, ручные сравнения конфигов.
- Воспроизводимость — только с доп. инструментами и скриптами.
- Полный пример: один файл flake.nix настраивает всё
Ниже — рабочая конфигурация хоста “myhost”. После её применения ничего руками делать не нужно (кроме запустить rebuild и перелогиниться, чтобы вступило в силу членство в группе docker).
{
description = "myhost declarative system";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
home-manager.url = "github:nix-community/home-manager/release-24.05";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, home-manager, ... }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
({ config, pkgs, ... }: {
# Базовые настройки и включение flakes/команд nix
nix.settings.experimental-features = [ "nix-command" "flakes" ];
system.stateVersion = "24.05";
time.timeZone = "Europe/Moscow";
i18n.defaultLocale = "ru_RU.UTF-8";
console.keyMap = "ruwin_alt_sh-UTF-8";
networking.hostName = "myhost";
networking.networkmanager.enable = true;
# Пользователь с ключом, sudo без пароля, нужные группы
users.users.me = {
isNormalUser = true;
description = "Me";
extraGroups = [ "wheel" "networkmanager" "docker" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAA... мой-ключ"
];
};
security.sudo.wheelNeedsPassword = false;
# SSH: только по ключу
services.openssh.enable = true;
services.openssh.settings.PasswordAuthentication = false;
# Docker
services.docker.enable = true;
# Nginx с готовым сайтом из store (никаких /var/www руками)
services.nginx.enable = true;
services.nginx.virtualHosts."localhost" = {
root = pkgs.writeTextDir "index.html" "<h1>It works from Nix store</h1>";
};
# PostgreSQL с предсозданной БД и пользователем
services.postgresql.enable = true;
services.postgresql.ensureDatabases = [ "app" ];
services.postgresql.ensureUsers = [
{ name = "app"; ensureDBOwnership = true; }
];
# Файрвол
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 22 80 443 ];
# Набор системных пакетов
environment.systemPackages = with pkgs; [
git curl htop vim docker-compose
];
})
# Пользовательская конфигурация через Home Manager (опционально)
home-manager.nixosModules.home-manager
{
home-manager.useUserPackages = true;
home-manager.users.me = { pkgs, ... }: {
home.stateVersion = "24.05";
programs.zsh.enable = true;
programs.direnv.enable = true;
programs.git = {
enable = true;
userName = "Me";
userEmail = "me@example.com";
};
};
}
];
};
};
}- Как применить (и всё готово)
- Сохранить файл как /etc/nixos/flake.nix (или в репозитории, затем скопировать).
- Выполнить:
sudo nixos-rebuild switch --flake /etc/nixos#myhost- Перелогиниться (только один раз), чтобы вступило в силу членство в группе docker.
- Что система сделает автоматически после одного ребилда
- Создаст пользователя “me” с SSH-ключом и правами sudo.
- Включит и настроит OpenSSH (логин только по ключу).
- Установит Docker, добавит пользователя в группу docker.
- Поднимет Nginx и отдаст страницу на http://localhost без ручных каталогов.
- Поднимет PostgreSQL, создаст БД app и пользователя app.
- Откроет порты 22/80/443 в файрволе.
- Установит нужные пакеты (git, vim, docker-compose и т.д.).
- Настроит zsh, direnv и git для пользователя через Home Manager.
- Все изменения будут атомарны и откатываемы (предыдущая генерация доступна в загрузчике).
- Итог
- В Debian/Arch/macOS ты собираешь систему командами и заметками.
- В NixOS ты описываешь желаемое состояние в одном файле и делаешь один rebuild.
- Никаких “ещё чуть‑чуть руками”: без apt/pacman/brew, без systemctl enable, без usermod, без ручного редактирования /etc.