Nix, NixOS a devenv — reprodukovateľné prostredia
Nix je purely functional package manager, ktorý pristupuje k buildovaniu softvéru ako k matematickej funkcii: rovnaké vstupy vždy produkujú bitovo identický výstup. Z tejto jednej myšlienky sa rozvinul celý ekosystém — NixOS (declarative linux distro), Nix flakes (moderný UX model), devenv.sh (štruktúrované dev environments) a Devbox (príjemnejšia abstrakcia od Jetify).
Pre DevOps tímy Nix rieši problémy, ktoré Docker rieši len čiastočne: bit-for-bit reprodukovateľnosť buildu, zdieľanie dev env medzi OS (macOS + Linux + WSL), rollback celého OS na predchádzajúcu konfiguráciu a elimináciu dependency hell naprieč projektami na jednom stroji.
Tento článok je zámerne hutný — Nix má strmú krivku učenia, ale keď ju zvládnete, vyrieši vám triedu problémov, ktoré iné nástroje nedokážu.
Prečo Nix — problém neurčitých buildov
Klasické package managery (apt, brew, pip, npm) inštalujú softvér do globálnych umiestnení (/usr/lib, /usr/local, ~/.npm). Dôsledky:
- Závislosti sa tlačia na seba — jeden projekt vyžaduje OpenSSL 1.1, druhý 3.0. Nemôžete mať oba naraz.
- "Works on my machine" — váš
node_modulesmá inú verziu než CI, pretože lokálny npm cache je starý. - Build nie je reprodukovateľný — spustíte
apt installdnes a zajtra, dostanete iné verzie. - Upgrade je nevratný — keď sa
/usr/lib/libfoo.so.3prepíše novšou verziou, staré aplikácie spadnú. - CI artefakty sa líšia bitovo medzi behmi — zmena timestamp v súbore znehodnotí Docker layer cache.
Nix na to ide z druhej strany. Každý balík má cryptographic hash závislostí a je uložený v unikátnom priečinku /nix/store/<hash>-<name>-<version>:
/nix/store/
├── 3xj4mpk7dhqbw5g5k2l9pq7s-openssl-1.1.1w/
├── a8dj29rp7lmk3n4v5b6c7x8z-openssl-3.0.11/
├── b9kl37qs8nmc4o5w6d7y8a1x-nodejs-20.10.0/
│ └── bin/node
└── c0lm48rt9opd5q6x7e8z9a2y-nodejs-22.3.0/
└── bin/node
Dôsledok: dve verzie OpenSSL môžu koexistovať. Každá aplikácia si v build-time natvrdo zapečatí cestu k svojej konkrétnej verzii. Žiadny LD_LIBRARY_PATH, žiadne symlinky, žiadna kolízia.
Nix, NixOS, flakes, devenv, Devbox — ako sa to má?
Ekosystém má viac vrstiev a mená sa často miešajú. Rýchla mapa:
| Vrstva | Čo to je | Kedy použiť |
|---|---|---|
| Nix (package manager) | CLI + daemon + store; funguje na Linux, macOS, WSL | Vývojár chce jeden dev env naprieč OS |
| nixpkgs | Monorepo s ~100 000 balíčkami (github.com/NixOS/nixpkgs) |
Zdroj balíkov pre všetko ostatné |
| Nix flakes | Experimentálny moderný UX — lock file, reprodukovateľnosť "out of the box" | Nové projekty (už 5+ rokov stabilné v praxi) |
| NixOS | Linuxová distribúcia postavená na Nix; celý OS je jedna configuration.nix |
Servery s GitOps, reproducible VMs |
| Home Manager | Declarative user-level config (dotfiles, shell, IDE) | Developer workstation ako kód |
| devenv.sh | Štruktúrovaný wrapper pre dev shell (services, processes, languages) | Team hľadá príjemnejší UX ako holé flakes |
| Devbox (Jetify) | JSON-based wrapper nad Nix, cieli na vývojárov bez Nix znalostí | Nechcete sa učiť Nix jazyk, len chcete Node 20 a PostgreSQL 16 |
Ak začínate v 2026, odporúčanie znie: flakes + devenv.sh. Flakes preto, lebo sú de-facto štandard; devenv preto, lebo skryje väčšinu boilerplate a pridá hot-reload services.
Nix derivations — čo sa deje pod kapotou
Derivation je základná jednotka v Nixe — recept, ako zo vstupov vyrobiť výstup. Celý nixpkgs nie je nič iné ako ~300 MB Nix kódu, ktorý definuje 100 000 derivations.
Minimálny príklad:
# hello.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
pname = "hello-sk";
version = "1.0.0";
src = pkgs.fetchurl {
url = "https://ftp.gnu.org/gnu/hello/hello-2.12.tar.gz";
sha256 = "086vqwk2wl8zfs47sq2xpjc9k066ilmkcyznznq7y4vmw31y115p"; # hello-2.12 (base32)
};
buildInputs = [ pkgs.gcc ];
buildPhase = "make";
installPhase = ''
mkdir -p $out/bin
cp hello $out/bin/
'';
}
Build:
nix-build hello.nix
# → ./result -> /nix/store/abc123...-hello-sk-1.0.0/
./result/bin/hello
# Hello, world!
Čo sa stalo:
- Nix spočítal hash zo všetkých vstupov (src tarball + gcc + mkDerivation skripty).
- Ak výsledok s týmto hashom už v store je, skončil okamžite.
- Inak spustil build v sandboxe (izolované prostredie bez internetu, iba deklarované vstupy).
- Výsledok uložil do
/nix/store/<hash>-hello-sk-1.0.0/a vytvoril./resultsymlink.
Kľúčový moment: build sandbox zabraňuje náhodným impure inputom. Žiadny $HOME/.gcc-cache, žiadne apt install pre "chýbajúcu" knižnicu. Ak to build potrebuje, musí to byť v buildInputs.
Nix flakes — moderný UX
Flakes sú novšia abstrakcia nad Nixom, ktorá rieši tri praktické problémy:
- Lock file —
flake.lockpresne zapíše, ktorý commit nixpkgs použiť. - Schéma — každý flake exportuje štruktúrované outputs (
packages,devShells,nixosConfigurations, ...). - Cross-reference — flakes môžu importovať iné flakes cez
inputs.
Minimálny flake.nix pre projekt:
{
description = "Aventera — statická travel stránka";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in {
# nix develop → dev shell
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_22
caddy
html-tidy
imagemagick
];
shellHook = ''
echo "Aventera dev shell ready"
echo "Node: $(node --version)"
'';
};
# nix build → hotový Docker image
packages.docker = pkgs.dockerTools.buildLayeredImage {
name = "aventera";
tag = "latest";
contents = [ pkgs.caddy ];
config.Cmd = [ "${pkgs.caddy}/bin/caddy" "run" ];
};
}
);
}
Použitie:
# Vstúpite do shellu so všetkými závislosťami
nix develop
# Spustite program, ale iba pre tento shell (bez "nainštalovania")
nix run nixpkgs#hello
# Buildnutie konkrétnej Output
nix build .#docker
docker load < result
flake.lock obsahuje presný SHA commit každého input:
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1711703276,
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
"type": "github"
}
}
}
}
Ak kolega v inom kúte sveta urobí nix develop, dostane bit-for-bit identický dev shell, aj o 2 roky. To je skutočný zmysel Nixu.
devenv.sh — štruktúrované dev environments
devenv (devenv.sh) je projekt od Cachix (tí, čo robia binary cache pre Nix), ktorý ponúka vysokoúrovňové API nad flakes. Namiesto buildInputs = [ pkgs.postgresql ] napíšete services.postgres.enable = true a devenv sa postará o spustenie, data dir, port, automatic migration atď.
# devenv.nix
{ pkgs, ... }:
{
# Jazyky
languages.javascript = {
enable = true;
package = pkgs.nodejs_22;
npm.enable = true;
};
languages.python = {
enable = true;
version = "3.12";
venv.enable = true;
};
# Služby (bežia ako procesy, nie Docker)
services.postgres = {
enable = true;
package = pkgs.postgresql_16;
initialDatabases = [
{ name = "aventera_dev"; }
];
settings = {
log_statement = "all";
};
};
services.redis.enable = true;
services.caddy = {
enable = true;
virtualHosts."localhost:8080" = {
extraConfig = ''
reverse_proxy localhost:3000
'';
};
};
# Extra balíčky
packages = with pkgs; [
mkcert
httpie
jq
];
# Processes (spustia sa cez `devenv up`)
processes.web.exec = "npm run dev";
processes.worker.exec = "npm run worker";
# Pre-commit hooky
pre-commit.hooks = {
prettier.enable = true;
eslint.enable = true;
shellcheck.enable = true;
};
# Env variables
env.DATABASE_URL = "postgres://postgres@localhost/aventera_dev";
}
# Enter shell
devenv shell
# Start all services + processes
devenv up
# Connect to DB
devenv shell -- psql $DATABASE_URL
Čo tým získate oproti Dockeri Compose:
- Žiadna Docker daemon overhead.
- Natívne binárky na vašom OS (macOS — rovnaký Postgres beží natívne, nie v VM).
devenv testspustí deterministický test run.devenv.locklock celé toolchain (Nixpkgs commit + devenv verzia).- Funguje v CI bez zmien.
Limitácie:
- Nefunguje na Windows (WSL áno).
- Niektoré komplexné services (napr. Kafka cluster) sú jednoduchšie v Docker Compose.
- Vaši kolegovia musia mať nainštalovaný Nix + devenv.
Devbox — Nix bez Nix jazyka
Devbox od Jetify má rovnaký cieľ ako devenv, ale cieli na vývojárov, ktorí sa nechcú učiť Nix jazyk. Konfigurácia je v JSON a API je zjednodušená.
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/main/.schema/devbox.schema.json",
"packages": [
"nodejs@22",
"postgresql@16",
"redis@7",
"caddy@latest"
],
"shell": {
"init_hook": [
"echo 'Aventera dev shell (Devbox)'"
],
"scripts": {
"dev": "npm run dev",
"test": "npm test"
}
}
}
devbox shell # vstúpi do env s node/postgres/redis/caddy
devbox run dev # spustí script "dev"
devbox services up postgres # spustí Postgres
Kedy Devbox vs devenv:
- Devbox — team má mix juniorov / jazykov, netreba pokročilé features, JSON stačí.
- devenv — team má Nix skúsenosti, potrebuje pokročilé pre-commit, process management, complex services config.
NixOS — operačný systém ako kód
NixOS posunie Nix z package manager na celý OS. /etc/nixos/configuration.nix definuje všetko — boot, kernel, služby, používatelia, firewall.
Ukážka jednoduchej konfigurácie servera:
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
# Boot
boot.loader.systemd-boot.enable = true;
boot.kernelPackages = pkgs.linuxPackages_6_6;
# Networking
networking = {
hostName = "sardonic";
firewall = {
enable = true;
allowedTCPPorts = [ 22 80 443 ];
};
};
# Users
users.users.peter = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAA... peter@laptop"
];
};
# Services
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."aventera.example.sk" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://localhost:3000";
};
};
security.acme = {
acceptTerms = true;
defaults.email = "admin@example.sk";
};
# System packages
environment.systemPackages = with pkgs; [
vim git htop tmux
];
# State version (nikdy neznižovať)
system.stateVersion = "24.11";
}
Aplikovanie:
sudo nixos-rebuild switch
# Alebo bez aktivácie, len build (rollback-friendly)
sudo nixos-rebuild boot # aplikuje pri ďalšom boote
sudo nixos-rebuild test # aplikuje len do RAM
Čo je fascinujúce: každý nixos-rebuild switch vytvorí novú "generáciu" systému. Ak niečo zlomíte:
# Zoznam generácií
nix-env --list-generations --profile /nix/var/nix/profiles/system
# Rollback na predchádzajúcu
sudo nixos-rebuild switch --rollback
# Alebo v GRUB menu vybrať konkrétnu generáciu
Rollback je ozajstný — nielen balíky, ale aj kernel, init scripts, služby. Neexistuje "pokazený upgrade" ktorý sa nedá undovať.
Home Manager — dotfiles ako kód
Home Manager prináša ten istý prístup na úroveň používateľa. Váš ~/.bashrc, ~/.vimrc, ~/.gitconfig — všetko deklaratívne.
# ~/.config/home-manager/home.nix
{ config, pkgs, ... }:
{
home.username = "peter";
home.homeDirectory = "/home/peter";
home.stateVersion = "24.11";
programs.git = {
enable = true;
userName = "Peter Boda";
userEmail = "peter@example.sk";
extraConfig = {
init.defaultBranch = "main";
pull.rebase = true;
};
delta.enable = true;
};
programs.neovim = {
enable = true;
vimAlias = true;
plugins = with pkgs.vimPlugins; [
vim-nix
telescope-nvim
nvim-treesitter
];
extraConfig = ''
set number relativenumber
set expandtab shiftwidth=2
'';
};
programs.zsh = {
enable = true;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [ "git" "docker" "kubectl" ];
};
};
home.packages = with pkgs; [
ripgrep fd bat fzf
lazygit
k9s kubectl
];
}
home-manager switch
Na novom stroji (Linux, macOS, WSL) stačí home-manager switch a máte identický setup.
Nix v CI/CD
Nix je v CI výhodnejší než Docker tam, kde chcete bit-for-bit reprodukovateľné artefakty. Typický GitHub Actions workflow:
# .github/workflows/build.yml
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Setup Cachix (binary cache)
uses: cachix/cachix-action@v14
with:
name: aventera
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build
run: |
nix build .#package
nix build .#docker
- name: Run tests
run: nix develop --command npm test
- name: Push Docker image
run: |
docker load < result
docker tag aventera:latest ghcr.io/peter/aventera:${{ github.sha }}
docker push ghcr.io/peter/aventera:${{ github.sha }}
Cachix zabezpečí, že artefakty, ktoré už niekto postavil, sa stiahnu z CDN namiesto rebuildu. Pre stredne veľký projekt to znamená rozdiel medzi 15-minútovým build-om a 90-sekundovým.
Reprodukovateľné Docker images bez Dockerfile
Jeden z najprakickejších use-case: dockerTools.buildLayeredImage. Vytvoríte Docker image z Nix derivation — bez Dockerfile, s deterministickými layer hashmi.
# flake.nix (výrez)
packages.dockerImage = pkgs.dockerTools.buildLayeredImage {
name = "aventera";
tag = "v1.0.4";
contents = with pkgs; [
caddy
cacert
tzdata
];
config = {
Cmd = [ "${pkgs.caddy}/bin/caddy" "run" "--config" "/etc/Caddyfile" ];
ExposedPorts."80/tcp" = {};
Env = [
"SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
"TZ=Europe/Bratislava"
];
};
# Skopíruje Caddyfile do /etc/
extraCommands = ''
mkdir -p etc
cp ${./Caddyfile} etc/Caddyfile
'';
};
Výsledok:
nix build .#dockerImage
docker load < result
# Loaded image: aventera:v1.0.4
Výhody oproti klasickému Dockerfile:
- Layer hash závisí výhradne od obsahu — rovnaký build dnes a zajtra = identický image.
- Žiadne
apt-get update && apt-get install(tie sú impure — verzie sa menia). - Multi-stage je natívny (Nix závislosti sú implicitne stage-ované).
- Layer optimalizácia —
buildLayeredImageautomaticky rozdelí balíčky do separátnych vrstiev podľa closure size.
Binary caches — Cachix a alternatívy
Nix builds sú deterministické, takže môžu byť zdieľané cez binary cache. Ak niekto postavil nodejs_22 pred vami, vy to sťahujete ako blob, nie rebuildujete.
Verejné cache:
- cache.nixos.org — predvolený, obsahuje väčšinu nixpkgs
- cache.flox.dev — Flox cache
- nix-community.cachix.org — komunitné balíčky
Vlastný cache cez Cachix:
# 1. Cache vytvorte cez webové UI na cachix.org, potom lokálne zaregistrujte token
cachix authtoken <token>
# 2. Pri builde push do cache
nix build --substituters https://aventera.cachix.org
cachix push aventera result
# 3. Zdieľanie s tímom — v flake.nix
{
nixConfig = {
extra-substituters = [ "https://aventera.cachix.org" ];
extra-trusted-public-keys = [
"aventera.cachix.org-1:AbCdEfGh..."
];
};
}
Samostatná Attic inštancia (self-hosted alternatíva k Cachix) je tiež populárna v komunitách, ktoré chcú vlastnú kontrolu.
Footguny a nepríjemné pravdy
Nix nie je stříbrná strela. Typické prekvapenia:
1. Strmá krivka učenia
Nix jazyk je funkcionálny, lenivý, dynamicky typovaný. Nie je to JSON. Väčšina nováčikov sa zasekne pri:
- Pochopení
withvsinherit - Rozdiele medzi
nix-env,nix-shell,nix run,nix develop - Error messages (ktoré sú notoricky zlé)
Investícia: rátajte 2-4 týždne na funkčnú znalosť pre seniorného DevOps inžiniera.
2. Disk space
/nix/store rastie rýchlo. Nie zriedkavo 50-100 GB po roku používania. Riešenie:
# Garbage collection — zmaže všetko nedostupné cez roots
sudo nix-collect-garbage -d
# Agresívnejšie: zmaže všetky generácie staršie než 7 dní
sudo nix-collect-garbage --delete-older-than 7d
# Optimalizácia — deduplikuje identické súbory cez hard links
sudo nix-store --optimise
3. Flakes sú stále "experimental" (formálne)
V upstream Nixe sú flakes formálne experimental feature — treba ich zapnúť:
# ~/.config/nix/nix.conf
experimental-features = nix-command flakes
V praxi sa používajú v produkcii niekoľko rokov a Determinate Systems Nix (odporúčaný inštalátor) flakes má zapnuté by-default a považuje ich za stable. Tooling okolo (devenv, Devbox, väčšina komunitných flakes) sa s flakes počíta. Riziko ich "odvolania" je v 2026 minimálne, ale občas sa pridajú nové príznaky, ktoré staršie Nixy nepoznajú.
4. macOS je second-class
Na macOS fungujú všetky základné veci, ale:
- Sandbox je slabší (žiadny chroot).
- Niektoré balíčky (Linux-specific tooling) jednoducho nie sú dostupné.
- Build time často pomalší (chýba niektoré binary caches pre aarch64-darwin).
5. Proprietárny softvér
Nixpkgs má unfree balíčky (VS Code, Chrome, NVIDIA drivers), ale musia byť explicitne povolené:
{ allowUnfree = true; }
Niektoré veľmi špecifické enterprise softvéry (SAP, Oracle, niektoré ovládače) sa do Nixpkgs nedostanú — musíte písať vlastné derivations.
6. Dokumentácia je fragmentovaná
Oficiálna dokumentácia, nix.dev, nixos.wiki, Zero to Nix, Discourse — každý zdroj má inú filozofiu a niektoré sú zastarané. Odporúčaný štart: nix.dev a zero-to-nix.com.
Kedy Nix použiť a kedy nie
Pustite sa do Nixu, ak:
- Robíte s dev tímom, ktorý sa dvíha na "works on my machine" — flakes/devenv to vyriešia.
- Staviate NixOS servery — infrastructure-as-code pre celý OS, rollback zadarmo.
- Potrebujete bit-for-bit reprodukovateľné Docker images.
- Robíte v reguloavnom prostredí (finance, healthcare) kde je supply chain proveniencia kritická.
- Máte viac projektov s konfliktnými dependencies na jednom stroji.
Nepúšťajte sa do Nixu, ak:
- Tím má < 3 ľudí a nikto nemá bandwidth na 2-4 týždne učenia.
- Cieľová platforma je Windows (native, nie WSL) — tam Nix nefunguje.
- Používate proprietárny software bez Nix derivácie a nechcete ju písať.
- Projekt je krátkodobý prototype — over-engineering.
Pragmatický kompromis: Devbox ako entry-level nástroj. Skryje Nix pod JSON rozhranie a tím si zvyká postupne.
Porovnanie s inými prístupmi
| Nix + flakes | Docker Compose dev | asdf / mise | Vagrant | |
|---|---|---|---|---|
| Reprodukovateľnosť | ✅ Bit-for-bit | ⚠️ Image digest, nie builds | ⚠️ Verzie, nie deps | ✅ VM image |
| OS prenositeľnosť | ✅ Linux + macOS + WSL | ✅ Všade (cez VM) | ✅ | ✅ |
| Dev/prod parita | ✅ Rovnaký derivation | ✅ Rovnaký image | ❌ | ⚠️ |
| Rýchlosť štartu | ✅ Natívne procesy | ⚠️ Docker overhead | ✅ | ❌ Pomaly VM |
| Krivka učenia | ❌ Strmá | ⚠️ Stredná | ✅ Plochá | ⚠️ Stredná |
| Rollback | ✅ Na úrovni OS | ❌ | ❌ | ⚠️ Snapshoty |
| Použitie v CI | ✅ Excelentné s Cachix | ✅ Štandard | ⚠️ Bash scripting | ❌ |
Migračná stratégia pre existujúci projekt
Ak máte projekt s npm install && docker-compose up, migrácia na Nix má zmysel urobiť postupne:
Krok 1 — Dev shell pre vývojárov (bez vplyvu na prod):
# V projekte vytvorte flake.nix s devShell
nix flake init --template github:nix-community/templates#nodejs
# Vývojári postupne prechádzajú z asdf/nvm na nix develop
Krok 2 — CI pipeline:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- run: nix develop --command npm test
Krok 3 — Docker image (voliteľné):
Keď flake dev shell funguje, pridajte packages.docker a porovnajte veľkosť obrazu. dockerTools.buildLayeredImage typicky produkuje 30-50% menšie images než klasický node:alpine base.
Krok 4 — NixOS servery (voliteľné): Najväčší skok. Zvažte len ak máte aspoň 5+ serverov a chcete infrastructure-as-code s rollbackom.
Zhrnutie
Nix rieši reálne DevOps problémy — reprodukovateľnosť buildov, konflikty dependencies, deklaratívny OS, rollback-friendly upgrades — ale platí sa za to strmou krivkou učenia.
V roku 2026 odporúčanie znie:
- Malý tím, rýchle zapojenie: Devbox (JSON, Nix skrytý).
- Stredný tím, chce pokročilé features: devenv.sh.
- Veľký tím, reprodukovateľné CI, vlastný toolchain: čisté flakes + Cachix.
- Servery s GitOps pre infraštruktúru: NixOS.
Nie každý projekt potrebuje Nix. Ale tam, kde "works on my machine" stojí tím reálne peniaze, Nix má najsilnejšie zbrane v brandži.
Ďalšie čítanie
- NixOS.org — oficiálna stránka
- nix.dev — moderná dokumentácia
- Zero to Nix — tutoriál od Determinate Systems
- nix-community — komunitné flakes a templates
- devenv.sh docs
- Devbox docs
- NixOS manual
- Home Manager manual
- Cachix docs
- NixOS & Flakes Book — začiatočnícky-friendly kniha