Nix и NixOS: декларативное управление серверами без побочных эффектов

Проблема: конфигурационный дрейф и dependency hell

Компания «ДатаФлоу» — платформа аналитики данных, 30 серверов на Ubuntu 22.04. Три инженера управляли инфраструктурой через Ansible. Инциденты, которые привели к поиску альтернативы:

  • Dependency hell: apt upgrade обновил libssl на 5 серверах из 30. Python-приложение сломалось на тех 5, остальные 25 работали — потому что apt запускался в разное время
  • Конфигурационный дрейф: один инженер руками поправил /etc/sysctl.conf на 3 серверах. Ansible playbook не знал об этих изменениях и перезатирал их при каждом прогоне
  • Невоспроизводимость: новый сервер, настроенный тем же Ansible playbook, работал иначе — потому что порядок установки пакетов влиял на итоговую конфигурацию
  • Откат: после неудачного обновления PostgreSQL 15→16 откат занял 6 часов ручной работы

NixOS решает все четыре проблемы архитектурно, а не процессно. Каждая конфигурация — это чистая функция: одинаковый вход → одинаковый результат. Всегда.

Nix package manager: основы

Nix можно использовать без NixOS — как пакетный менеджер на любом Linux или macOS. Каждый пакет устанавливается в уникальный путь с хешем зависимостей:

# Установка Nix
sh <(curl -L https://nixos.org/nix/install) --daemon

# Запуск программы без установки
nix run nixpkgs#htop
nix run nixpkgs#python312

# Временное окружение с набором инструментов
nix shell nixpkgs#nodejs_22 nixpkgs#yarn nixpkgs#jq
node --version  # v22.x — доступен только в этой сессии

# Где физически хранятся пакеты
ls /nix/store/ | head -3
# 0a1b2c3d-nodejs-22.0.0
# 4e5f6g7h-openssl-3.2.1
# 8i9j0k1l-python-3.12.3

Ключевое отличие от apt/yum: пакеты никогда не перезаписываются. Обновление создаёт новую версию рядом. Откат — переключение симлинка на предыдущую версию за 1 секунду.

# Все поколения системы
nix profile history
# Generation 1: nodejs-20.0.0, python-3.11.0 (2026-01-15)
# Generation 2: nodejs-22.0.0, python-3.12.3 (2026-04-10) [current]

# Откат на предыдущее поколение
nix profile rollback

NixOS: вся ОС как одна конфигурация

NixOS — дистрибутив, в котором вся операционная система описана в одном файле configuration.nix. Нет «установки пакетов» — есть описание желаемого состояния.

# /etc/nixos/configuration.nix
{ config, pkgs, ... }: {
  # Сеть
  networking.hostName = "web-01";
  networking.firewall.allowedTCPPorts = [ 22 80 443 ];

  # SSH
  services.openssh.enable = true;
  services.openssh.settings.PasswordAuthentication = false;

  # Nginx
  services.nginx = {
    enable = true;
    virtualHosts."api.dataflow.ru" = {
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        proxyPass = "http://127.0.0.1:8000";
      };
    };
  };

  # PostgreSQL
  services.postgresql = {
    enable = true;
    package = pkgs.postgresql_16;
    settings = {
      shared_buffers = "4GB";
      effective_cache_size = "12GB";
      max_connections = 200;
    };
  };

  # Пакеты
  environment.systemPackages = with pkgs; [
    vim htop tmux curl jq git
  ];

  # Пользователи
  users.users.deploy = {
    isNormalUser = true;
    extraGroups = [ "wheel" "docker" ];
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAA... deploy@ci"
    ];
  };

  # Автообновление
  system.autoUpgrade.enable = true;
  system.autoUpgrade.flake = "github:dataflow/infra";

  system.stateVersion = "24.11";
}
# Применяем конфигурацию
sudo nixos-rebuild switch

# Откат на предыдущую конфигурацию — 2 секунды
sudo nixos-rebuild switch --rollback

# Список всех поколений системы
nix profile history --profile /nix/var/nix/profiles/system
Совет: При откате NixOS не восстанавливает данные (БД, файлы). Он откатывает пакеты, конфигурацию сервисов и systemd-юниты. Для данных используйте отдельную стратегию бэкапов.

Flakes: воспроизводимость и lock-файлы

Nix Flakes — механизм фиксации зависимостей через flake.lock (аналог package-lock.json). Гарантия: два разных инженера получат идентичную систему.

# flake.nix — корень проекта инфраструктуры
{
  description = "DataFlow infrastructure";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
    deploy-rs.url = "github:serokell/deploy-rs";
  };

  outputs = { self, nixpkgs, deploy-rs }: {
    nixosConfigurations = {
      web-01 = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./hosts/web-01/configuration.nix
          ./modules/base.nix
          ./modules/monitoring.nix
        ];
      };
      db-01 = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./hosts/db-01/configuration.nix
          ./modules/base.nix
          ./modules/postgresql.nix
        ];
      };
    };

    # Деплой через deploy-rs
    deploy.nodes = {
      web-01 = {
        hostname = "10.0.1.10";
        profiles.system = {
          user = "root";
          path = deploy-rs.lib.x86_64-linux.activate.nixos
            self.nixosConfigurations.web-01;
        };
      };
    };
  };
}
# Обновить все зависимости
nix flake update

# Обновить только nixpkgs
nix flake lock --update-input nixpkgs

# Собрать конфигурацию web-01 без деплоя (проверка)
nix build .#nixosConfigurations.web-01.config.system.build.toplevel

# Деплой на все серверы
deploy .

Результаты миграции «ДатаФлоу»

Миграция 30 серверов на NixOS заняла 8 недель (при сохранении работоспособности сервисов):

МетрикаUbuntu + AnsibleNixOS + Flakes
Время настройки нового сервера2-4 часа15 минут
Время отката после сбоя1-6 часов5 секунд
Конфигурационный дрейфПостоянноНевозможен*
Воспроизводимость между серверами~95%100%
Инциденты из-за обновлений3-4/мес0

* Дрейф невозможен для декларативно описанных компонентов. Данные в /var и пользовательские файлы — отдельная история.

Минусы NixOS: крутая кривая обучения (язык Nix непривычен), не все пакеты доступны в nixpkgs, проприетарное ПО может потребовать ручной упаковки. Если команда маленькая и нет готовности учить Nix — Ansible остаётся разумным выбором.

Часто задаваемые вопросы

Да, Nix как пакетный менеджер работает на любом Linux и macOS. Вы можете использовать nix shell для изолированных окружений, nix develop для dev-окружений проектов, и nix build для воспроизводимых сборок — всё это без замены дистрибутива.

Да, но с оговорками. NixOS управляет конфигурацией PostgreSQL/MySQL, но данные хранятся в /var/lib/ и не подвержены атомарным обновлениям. Для баз данных нужна отдельная стратегия бэкапов и миграций. NixOS гарантирует, что версия PostgreSQL и её конфигурация одинаковы на всех серверах.

NixOS поддерживает Docker через virtualisation.docker.enable = true. Но часто Docker не нужен: Nix сам обеспечивает изоляцию и воспроизводимость. Для OCI-образов есть nix2container и dockerTools — сборка Docker-образов без Dockerfile, с минимальным размером.

Базовый уровень (установка пакетов, nix shell) — 1-2 дня. Написание configuration.nix для NixOS — 1-2 недели. Flakes, модули, overlay-ы — 1-2 месяца. Язык Nix функциональный и непривычен для тех, кто работал только с императивными языками.

Ansible — проще начать, работает с любым дистрибутивом, огромное сообщество. NixOS — гарантированная воспроизводимость, атомарные обновления, мгновенный откат. Для команды из 1-3 человек с 5-10 серверами Ansible достаточно. Для 20+ серверов с жёсткими требованиями к consistency — NixOS окупится.

Нужна помощь с внедрением?

Настроим, оптимизируем и возьмём на поддержку вашу инфраструктуру. 15+ лет опыта, 8 серверов Dell Xeon в дата-центре МТС.

📞 Связаться с нами

Комментарии 0

Оставить комментарий

7 + 6 =