presentation-nix-flakes/prezentace.md
2025-03-15 08:09:19 +01:00

11 KiB

marp class paginate footer
true invert true Albert Vala, Filip Kohout, Nix flakes & Nix command

Nix flakes & Nix command


Nix Command

  • Nové CLI pro Nix
  • Podpora Flakes

Porovnání

nix-shell -p cowsay #Old
nix shell nixpkgs#cowsay #New
nix run nixpkgs#cowsay #New

Příkazy

Command Na
flake new Vytvoření flaky z template
develop Build environment shell
shell temp shell s nějakým programem
config check Check configu na potenciální chyby
run Spustí output z flaky

Flakes

  • Proč Flakes?

  • Použití lockfiles pro deterministické buildy

  • Jednoduchá správa vstupů (flake inputs)

  • Na co lze Flakes použít?

  • Správa systémové konfigurace

  • Vývojové prostředí

  • Balíčkování

  • Nástroje pro deployment


Nix command + flakes

  • dočasný shell
nix shell nixpkgs#alejandra
nix shell github:kamadorueda/alejandra
  • zobrazení atributů
nix flake show github:kamadorueda/alejandra

Jak použít flakes na systémovou configuraci?

  • Flakes používáme jen na správu input a output atributů
  • Zbytek konfigurace používá inputy definované ve flake.nix

# flake.nix
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    zen-browser.url = "github:0xc000022070/zen-browser-flake";
  };
  outputs = inputs @ {
    nixpkgs,
    home-manager,
    zen-browser,
    ...
  }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = false;
            home-manager.useUserPackages = true;
            home-manager.extraSpecialArgs = {inherit zen-browser;};
            home-manager.users.nixFreak = import ./home.nix;
          }
        ];
      };
    };
  };
}

# home.nix
{
  zen-browser,
  config,
  pkgs,
  ...
}: {
  home.username = "nixFreak";
  home.homeDirectory = "/home/nixFreak";
  home.stateVersion = "24.05";
  home.packages = with pkgs;
    [
      cowsay
    ]
    ++ [
      zen-browser.packages."${system}".default
    ];
  programs.home-manager.enable = true;
}

# configuration.nix
{
  config,
  lib,
  pkgs,
  ...
}: {
  imports = [
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
  ];

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  users.users.nixFreak = {
    isNormalUser = true;
    extraGroups = ["wheel"];
  };
  system.stateVersion = "25.05";
}

Inputs

  • nix flake metadata --json | jq - zobrazí vstupy
  • lock aktuální verze
  • nix flake update - aktualizace všech vstupů
  • nix flake update [home-manager] - aktualizace jednoho vstupu
 inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
    nixpkgs-current = "github:nixos/nixpkgs?ref=3058cf84bce1aba7b1820cb24319a171572217ba-dirty";
 }

Nixos-rebuild

  • Je to jen bash script
nixos-rebuild --flake
nh os switch
nix build /etc/nixos#nixosConfigurations.nixos.config.system.build.toplevel
./result/bin/switch-to-configuration switch

Remote building

  • nixos-rebuild --target-host nixFreak@192.168.8.32 switch --flake .#default

  • --use-remote-sudo

  • --build-host - konfigurace bude použita na tomto zařízení

  • --target-host - konfigurace bude použita na cíleném zařízení

  • nix.settings.trusted-users


Virtual machine

  • nix run github:nix-community/nixos-generators -- -c ./flake.nix --flake '#default' -f vm --disk-size 20480
  • nixos-rebuild build-vm --flake ~/my-system-flake#default
  • možnost generovat pro různé platformy (Amazon E2C, Docker, ISO, Proxmox, VMware, vagrant, qcow, ...)
  • https://github.com/nix-community/nixos-generators

Nix Shell

  • nix-shell ./
# shell.nix
{pkgs ? import <nixpkgs> {}}:
pkgs.mkShell {
  packages = [
    (pkgs.python311.withPackages(pypkgs: with pypkgs; [
      requests
      numpy
      pygobject3
    ]))
  ]
}

#flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };
  outputs = {
    self,
    nixpkgs,
    flake-utils,
  }:
    flake-utils.lib.eachDefaultSystem
    (
      system: let
        pkgs = import nixpkgs {
          inherit system;
        };
      in
        with pkgs; {
          devShells.default = mkShell {
            packages = [
              (pkgs.python311.withPackages (pypkgs:
                with pypkgs; [
                  requests
                  numpy
                  pygobject3
                ]))
            ];
          };
        }
    );
}

Nix language

  • nix-repl nebo nix-instantiate --eval foo.nix
# Deklarace setu
 foo = {
  bar = "test"
 }

# "Čtení" setu (evaluation)
foo.bar

# Let-In syntaxe
let 
  foo = {
    bar = "test"
  };
in
foo.bar

# Rekurze
 foo = rec {
  bar = 10;
  ham  = 5;
  eggs =  bar + ham;
 }
# Použití with
 environment.systemPackages = with pkgs; [
  neovim
  wireshark
 ];

Funkce

# Jednoduchá funkce
let 
 bar = eggs: eggs + 1;
in
 bar 3 # -> 4

# Funkce s více parametry
let 
 bar = eggs: bacon: (eggs+1) * bacon;
in
bar 3 7 # -> 28

let 
 bar = { bacon, eggs }: bacon + eggs;
in
 bar { bacon = 10; eggs = 15; }
  • konfigurační soubory jsou funkce
# configuration.nix
{inputs, pkgs}:
{
  environment.systemPackages = [
    inputs.zen-browser.packages.${system}.default
    pkgs.gcc
  ];
}

let 
 bar = { bacon ? 10, eggs, ... }: bacon + eggs;
in
 bar { eggs = 15; bread = 30 }
let 
 bar = { bacon ? 10, ... }@arguments: 
  bacon + arguments.eggs;
in
 bar { eggs = 15; bread = 30; }

 outputs = inputs @ {
    nixpkgs,
    home-manager,
    zen-browser,
    ...
  }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
...

Jak zabalit aplikaci do flake?


 outputs = {self, ...} @ inputs: let
    supportedSystems = ["aarch64-linux" "i686-linux" "x86_64-linux"];
    forAllSystems = inputs.nixpkgs.lib.genAttrs supportedSystems;
    nixpkgsFor =
      forAllSystems (system: import inputs.nixpkgs {inherit system;});
  in {
    packages = forAllSystems (system: let
      pkgs = nixpkgsFor.${system};
    in {
      default = self.packages.${system}.nix-install;

      nix-install = pkgs.writeShellApplication {
        name = "nix-install";
        runtimeInputs = with pkgs; [git busybox gum];
        text = ''
          echo "This is shell aplication in flake"
        '';
      };
    });

    apps = forAllSystems (system: {
      default = self.apps.${system}.nix-install;

      nix-install = {
        type = "app";
        program = "${self.packages.${system}.nix-install}/bin/nix-install";
      };
    });
  };

├───apps
│   ├───aarch64-linux
│   │   ├───default: app
│   │   └───nix-install: app
│   ├───i686-linux
│   │   ├───default: app
│   │   └───nix-install: app
│   └───x86_64-linux
│       ├───default: app
│       └───nix-install: app
└───packages
    ├───aarch64-linux
    │   ├───default: package 'nix-install'
    │   └───nix-install: package 'nix-install'
    ├───i686-linux
    │   ├───default: package 'nix-install'
    │   └───nix-install: package 'nix-install'
    └───x86_64-linux
        ├───default: package 'nix-install'
        └───nix-install: package 'nix-install'

  • spuštění aplika e pomocí nix run
  • https://github.com/nixFreak/testApp
  • nix run github:nixFreak/testApp
  • nebo přidání do flake inputů
 environment.systemPackages = [
    inputs.install-script.packages.${system}.default
    inputs.zen-browser.packages.${system}.default
 ];

Nix writers

  • Jednoduchý způsob přidávání skriptů v různých programovacích jazycích do systému
  • Rozdíl oproti klasickému pkgs.writeShellScriptBin či balíčkovaání skriptu do derivace
  • nixpkgs - pro všechny možnosti konfigurace skriptů
  • https://nixos.wiki/wiki/Nix-writers - wiki

pkgs.writers.writeBash "hello-world-bash" {}
''
echo "Hello world!"
''

pkgs.writers.writePython3 "hello-world-python" {}
''
print("Hello world!")
''

pkgs.writers.writeRust "hello-world-rust" {}
''
fn main() {
    println!("Hello world!")
}
''

pkgs.writers.writePython3 "hello-world-python"
{
    libraries = [ pkgs.python3Packages.requests ];

    makeWrapperArgs = [
        "--prefix", "PATH", ":", "${pkgs.sl}/bin",
    ];
}

''
print("Hello world!")
''

Rozumíte?


{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    zen-browser.url = "github:0xc000022070/zen-browser-flake";
  };
  outputs = inputs @ {
    nixpkgs,
    home-manager,
    zen-browser,
    ...
  }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = false;
            home-manager.useUserPackages = true;
            home-manager.extraSpecialArgs = {inherit zen-browser;};
            home-manager.users.nixFreak = import ./home.nix;
          }
        ];
      };
    };
  };
}


Používejte Nix!