NixOS — how I use itNixOS — kako ga ja koristim
Stefan Matić
Built with Claude Code.Napravljeno uz Claude Code.
Nothing keeps a record of what you did to the system.Nigdje ne ostaje zapisano šta si uradio sa sistemom.
package managerpackage manager
Installs packages into /nix/store, each version side by side. Runs on any Linux distro and on macOS.Instalira pakete u /nix/store, svaku verziju odvojeno. Radi na bilo kojem Linux distrou i na macOS-u.
languagejezik
The language you write packages and configs in. Same name, which doesn't help.Jezik u kojem se pišu paketi i konfiguracija. Isto ime, što ne pomaže.
Linux distroLinux distro
A distro built on Nix. Kernel, services, users and settings are all defined in Nix files.Distro napravljen na Nixu. Kernel, servisi, korisnici i postavke su definisani u Nix fajlovima.
You can use Nix without NixOS. Most of this talk is about NixOS.Nix možeš koristiti i bez NixOS-a. Ovo predavanje je uglavnom o NixOS-u.
$ sudo apt install docker.io $ sudo systemctl enable --now docker $ sudo usermod -aG docker me
virtualisation.docker.enable = true; users.users.me.extraGroups = [ "docker" ];
# hosts/zvijer/configuration.nix (excerpt) imports = [ ./hardware-configuration.nix ../_common/client.nix ../../system/security/yubikey.nix ]; boot.loader.grub = { enable = true; efiSupport = true; configurationLimit = 20; theme = pkgs.sleek-grub-theme.override { withStyle = "dark"; }; }; services.nordvpn.enable = true; hardware.openrazer = { enable = true; users = [ userSettings.username ]; };
The full file is about 400 lines. sudo nixos-rebuild switch makes the system match it.Cijeli fajl ima oko 400 linija. sudo nixos-rebuild switch uskladi sistem s njim.
git logMoja GPU historija, direktno iz git log-aNew 5070 Ti GPU setupPin kernel to 6.18 because nvidia sucks assRestore 6900XT GPU and remove nvidia bloatzvijer: migrate GPU to NVIDIA RTX 5070 TiEach swap is a commit: drivers, Wayland variables, Ollama ROCm → CUDA. The last one was 3 files, about 40 lines.Svaka zamjena je jedan commit: drajveri, Wayland varijable, Ollama ROCm → CUDA. Zadnja je bila 3 fajla, oko 40 linija.
Every rebuild is also a generation. If one doesn't work, boot the previous one from GRUB, or:Svaki rebuild je i nova generacija. Ako nešto ne radi, butaš prethodnu iz GRUB-a, ili:
$ sudo nixos-rebuild switch --rollback
flake.nix: inputs (nixpkgs, Home Manager, …) and outputs (machines, packages, dev shells)Flake je repo s flake.nix: inputi (nixpkgs, Home Manager, …) i outputi (mašine, paketi, dev shellovi)flake.lock pins every input to an exact commit — mine pins 37flake.lock zaključa svaki input na tačan commit — moj ih ima 37nixos-rebuild switch --flake .#ZVIJERSvaka mašina je output: nixos-rebuild switch --flake .#ZVIJEROfficially:Zvanično: still an experimental feature in Nix, since 2021. You turn it on yourself:i dalje eksperimentalna opcija u Nixu, od 2021. Uključuješ je sam:
nix.settings.experimental-features = [ "nix-command" "flakes" ];
In practice:U praksi: most configs, tutorials and tools start with flakes. The community treats them as stable.većina configova, tutorijala i alata kreće od flakeova. Zajednica ih smatra stabilnim.
# flake.nix (simplified) { inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; home-manager.url = "github:nix-community/home-manager"; nix-darwin.url = "github:nix-darwin/nix-darwin/master"; }; outputs = { nixpkgs, ... }: { nixosConfigurations.ZVIJER = nixpkgs.lib.nixosSystem { modules = [ ./hosts/zvijer/configuration.nix ]; }; }; }
gitlab.com/stefan-matic/nixos-config
Same approach on a Mac: system settings, packages and services in Nix files. It manages macOS, it doesn't replace it.Isti pristup na Macu: sistemske postavke, paketi i servisi u Nix fajlovima. Upravlja macOS-om, ne zamjenjuje ga.
$ darwin-rebuild switch --flake .#macbook
# hosts/macbook + hosts/_common/darwin.nix (excerpt) security.pam.services.sudo_local.touchIdAuth = true; homebrew = { enable = true; casks = [ "ghostty" "raycast" "slack" "keepassxc" ]; }; home-manager.users.${userSettings.username} = { imports = [ ../../home/darwin.nix ]; };
Home Manager writes the dotfiles: ~/.config is generated from these files.Home Manager piše dotfileove: ~/.config se generiše iz ovih fajlova.
Change a shared file → every machine that imports it gets the change on its next rebuild.Promijeniš zajednički fajl → svaka mašina koja ga importuje dobije promjenu na sljedećem rebuildu.
hardware-configuration.nix.Instaliraš NixOS s USB-a. Instaler generiše hardware-configuration.nix.hosts/<machine>/.Kloniraš repo i kopiraš taj fajl u hosts/<mašina>/.$ git clone https://gitlab.com/stefan-matic/nixos-config ~/.dotfiles $ sudo nixos-rebuild switch --flake ~/.dotfiles#starlabs
Packages, services, shell, editor, desktop, keybindings, fonts.Paketi, servisi, shell, editor, desktop, prečice, fontovi.
Logging into accounts, SSH keys, your files (Syncthing handles those for me).Prijava na naloge, SSH ključevi, tvoji fajlovi (to mi rješava Syncthing).
3–4 Contabo VPSes running dev and staging for an app I built with friends. Contabo only offered Ubuntu 24.04. nixos-infect turns a running Linux into NixOS, in place:3–4 Contabo VPS-a za dev i staging aplikacije koju sam pravio s prijateljima. Contabo je nudio samo Ubuntu 24.04. nixos-infect pretvori Linux koji već radi u NixOS, na licu mjesta:
/old-root, SSH keys are keptrestartuje; stari sistem se premjesti u /old-root, SSH ključevi ostajuFrom the README: "so named because of the high likelihood of rendering a system inoperable." Fresh servers only.Iz README-a: „so named because of the high likelihood of rendering a system inoperable." Samo na novim serverima.
# fresh Contabo Ubuntu 24.04 VPS, root, SSH keynovi Contabo Ubuntu 24.04 VPS, root, SSH ključ # Contabo names it vmi123456.contaboserver.net;Contabo ga nazove vmi123456.contaboserver.net; # NixOS doesn't accept dots in the hostnameNixOS ne prihvata tačke u hostnameu $ hostname myserver $ curl https://raw.githubusercontent.com/elitak/\ nixos-infect/master/nixos-infect \ | NIX_CHANNEL=nixos-25.11 bash -x # …a few minutes and a reboot later…par minuta i jedan reboot kasnije $ ssh root@myserver [root@myserver:~]# nixos-version 25.11 …
git log shows when and why something changed.Config u gitu. git log pokaže kad je i zašto nešto promijenjeno.nix shell nixpkgs#htop — gone when the shell closes.Probaj bez instaliranja. nix shell nixpkgs#htop — nestane kad zatvoriš shell.flake.lock pins every input. All machines get the same versions until I run nix flake update.Zaključane verzije. flake.lock zaključa svaki input. Sve mašine imaju iste verzije dok ne pokrenem nix flake update.One approach for every language, instead of nvm, pyenv, rbenv, tfenv, sdkman…Jedan pristup za sve jezike, umjesto nvm, pyenv, rbenv, tfenv, sdkman…
$ cd ~/Workspace/project-a $ devbox init $ devbox add terraform@1.5.7 nodejs@20 awscli2 $ devbox generate direnv && direnv allow $ terraform version # Terraform v1.5.7 $ cd ../project-b $ terraform version # Terraform v1.4.0 $ cd ~ && terraform version zsh: command not found: terraform
devbox.json lists the tools and versions; it goes into the project's gitdevbox.json sadrži alate i verzije; ide u git projektacd in and unloads it when you leavedirenv učita okruženje kad uđeš u folder, a ukloni ga kad izađešdevShell + use flake in .envrcIsta ideja bez devboxa: flake devShell + use flake u .envrc# hosts/zvijer/configuration.nix (top) { config, pkgs, lib, inputs, ... }: let env = import ./env.nix { inherit pkgs; }; inherit (env) systemSettings userSettings; in { home-manager.users.${userSettings.username} = { imports = [ ../../home/stefanmatic.nix ]; }; }
The whole file is a function. inherit copies names into scope. let … in defines local values.Cijeli fajl je funkcija. inherit kopira imena u scope. let … in definiše lokalne vrijednosti.
[ pkgs.callPackage ./foo { } ]
This is a list of three items: a function, a path and an empty set. List items and function arguments are both separated by spaces.Ovo je lista od tri stavke: funkcija, putanja i prazan set. I stavke liste i argumenti funkcije se odvajaju razmakom.
[ (pkgs.callPackage ./foo { }) ]
It's a functional language. Most people learn it by reading other people's configs.To je funkcionalni jezik. Većina ga nauči čitajući tuđe configove.
A 6-line module that imports a file only when an option is on:Modul od 6 linija koji importuje fajl samo kad je opcija uključena:
{ config, lib, ... }: {
options.services.myapp.enable =
lib.mkEnableOption "myapp";
imports = lib.optional
config.services.myapp.enable ./extra.nix;
}
The trace points into nixpkgs internals, not your file. Newer Nix versions add hints like the one on the right; many errors still don't have one.Trace pokazuje na interni kod nixpkgs-a, ne na tvoj fajl. Novije verzije Nixa dodaju savjete kao ovaj desno; mnoge greške ih i dalje nemaju.
error:
… while evaluating the attribute
'config.services.myapp.enable'
at /nix/store/r5l6…-source/lib/modules.nix:404:9
… while calling the 'seq' builtin
at /nix/store/r5l6…-source/lib/modules.nix:404:18
… while evaluating the module argument
`config' in ":anon-1":
… if you get an infinite recursion here, you
probably reference `config` in `imports`.
(stack trace truncated; use '--show-trace')
error: infinite recursion encountered
/bin/bash, no libraries in /usr/libSkinuti binarni fajlovi često ne rade: nema /bin/bash, nema biblioteka u /usr/libsearch.nixos.org for packages and every NixOS optionsearch.nixos.org za pakete i sve NixOS opcijeprograms.nix-ld.enable = true; for most downloaded binariesprograms.nix-ld.enable = true; za većinu skinutih binarnih fajlovaIt's not a fix for everything. A lot of things don't work out of the box — they take tweaking and trial and error.Nije rješenje za sve. Dosta stvari ne radi odmah — treba ih podešavati i isprobavati.
configuration.nix; add flakes and Home Manager laterPočnite s jednim configuration.nix; flakeove i Home Manager dodajte kasnijeIf you didn't like this talk:Ako vam se predavanje nije svidjelo:
$ sudo nixos-rebuild switch --rollback