🔴 Advanced

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:

  1. Závislosti sa tlačia na seba — jeden projekt vyžaduje OpenSSL 1.1, druhý 3.0. Nemôžete mať oba naraz.
  2. "Works on my machine" — váš node_modules má inú verziu než CI, pretože lokálny npm cache je starý.
  3. Build nie je reprodukovateľný — spustíte apt install dnes a zajtra, dostanete iné verzie.
  4. Upgrade je nevratný — keď sa /usr/lib/libfoo.so.3 prepíše novšou verziou, staré aplikácie spadnú.
  5. 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:

  1. Nix spočítal hash zo všetkých vstupov (src tarball + gcc + mkDerivation skripty).
  2. Ak výsledok s týmto hashom už v store je, skončil okamžite.
  3. Inak spustil build v sandboxe (izolované prostredie bez internetu, iba deklarované vstupy).
  4. Výsledok uložil do /nix/store/<hash>-hello-sk-1.0.0/ a vytvoril ./result symlink.

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:

  1. Lock fileflake.lock presne zapíše, ktorý commit nixpkgs použiť.
  2. Schéma — každý flake exportuje štruktúrované outputs (packages, devShells, nixosConfigurations, ...).
  3. 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 test spustí deterministický test run.
  • devenv.lock lock 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 — buildLayeredImage automaticky 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í with vs inherit
  • 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