Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PyCon 25: Nix(OS) for Python Developers

PyCon 25: Nix(OS) for Python Developers

How do you onboard new colleagues in 2025? How long does it take? Would you love a standardized setup under version control that everyone can customize for themselves? A stable desktop setup, reinstalled in just minutes. It can be done.

This talk was given in Italian at PyCon 25, Bologna, Italy. All slides are provided in English.

Original slides at https://slides.com/bittner/pycon25-nixos-for-python-developers

Related blog post: https://painless.software/nixos-for-python-developers

Avatar for Peter Bittner

Peter Bittner

May 29, 2025
Tweet

More Decks by Peter Bittner

Other Decks in Technology

Transcript

  1. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  2. Digital Agency Problems Failing projects (over time, over budget) Slow

    releases (manual, big bang) Technical debt & Kubernetes Cloud complexity (multi/hybrid) Inefficient processes (onboarding) AI will replace us all 😱 ✅ NixOS ✅ NixOS ✅ Juju & Charmed Operators ✅ Modern Continuous Delivery ✅ Continuous Delivery ✅ Fix-Price Projects & Agile
  3. Development Process push code open PR/MR approve production system build

    server feature branch review system Continuous Delivery (CI/CD) “ Release early, release often! ⎘
  4. Easy Replacement Portable, declarative configuration. Effortless upgrades of hardware and

    software. 1. Resilience Built-In Work on any office owned computer. Continue where you left off when device gets dropped or stolen. ➜ Make installation and backup fully automatic, restore data upon login. 2. A Disposable Unit Fun Team Investment Learn by improving a shared setup. Solve problems together. ➜ Treat every machine like a container with a data volume. Resist manual config changes. Get into the IaC mindset, naturally. 3.
  5. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  6. Package Manager & Distro Nix = purely functional package manager

    Nix store = /nix/store (contains packages aka derivations) Nix expressions = functional language to describe/build a package NixOS = Linux distribution based on & built entirely from Nix NixOS config = /etc/nixos/configuration.nix (default, example) FHS ?!?
  7. Functional?!? WTF! foo = [99, 3, 4, 0] bar =

    sorted(foo) inverse = list(reversed(bar)) result = foo.sort() print(result) # None 1 id(foo) # 140428019716160 2 3 4 id(bar) # 140428019721728 5 6 7 print(inverse) # [99, 4, 3, 0] 8 9 # not pure functional 10 11 id(foo) # 140428019716160 12 print(foo) # [0, 3, 4, 99] 13 14 upper_words = list(map(str.upper, words)) upper_list = [str.upper(s) for s in words] salutation = "Ciao" if friend else "Buongiorno" (lambda :-1)() # -1 sorted(words, key=lambda s: -len(s)) # ..., Ciao words = ["Ciao", "Python", "Italia"] 1 2 3 4 print(upper_words) # ['CIAO', PYTHON', 'ITALIA'] 5 print(upper_list) # ['CIAO', PYTHON', 'ITALIA'] 6 7 8 9 10 11 “ list comprehensions “ set comprehensions “ dictionary comprehensions “ generator comprehensions “ lambda expressions “ built-in functions
  8. Commands & Places Excutables /run/current-system/sw/bin/ User executables /etc/profiles/per-user/<username>/bin/ Application data

    /run/current-system/sw/share/ User app data /etc/profiles/per-user/<username>/share/ Application icons /run/current-system/sw/share/icons/hicolor/scalable/apps/org.gnome.Epiphany.svg User app icons /etc/profiles/per-user/<username>/share/icons/ Autostart items /run/current-system/sw/etc/xdg/autostart Interesting Places New (think "Python 3") Old (think "Python 2")
  9. configuration.nix $ tree /etc/nixos /etc/nixos |-- configuration.nix `-- hardware-configuration.nix #

    Edit this configuration file to define what s { config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; boot.loader.systemd-boot.enable = true; networking.hostName = "nixos"; networking.networkmanager.enable = true; time.timeZone = "Europe/Rome"; i18n.defaultLocale = "en_US.UTF-8"; programs.firefox.enable = true; environment.systemPackages = with pkgs; [ vim ]; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # Do not modify this file! It was generated by { config, lib, pkgs, modulesPath, ... }: { boot.kernelModules = [ "kvm-intel" ]; fileSystems."/" = { device = "/dev/disk/by-uuid/5a42e090-37b7"; fsType = "ext4"; }; networking.useDHCP = lib.mkDefault true; } 1 2 3 4 5 6 7 8 9 10 11
  10. Apply Your Changes $ sudo nixos-rebuild [switch|boot|test] ... Done. The

    new configuration is /nix/store/j6a42... $ nixos-rebuild --use-remote-sudo [switch|boot|test] ... Done. The new configuration is /nix/store/j6a42... a b Recommended
  11. Use Version Control $ sudo su - # cd /etc/nixos

    # git init && git add -v . # git commit -m "Profit!" $ cp -r /etc/nixos ~/.nixos-config $ cd ~/.nixos-config $ git init && git add -v . $ git commit -m "Profit!" $ git push origin main $ sudo rm /etc/nixos/* $ nixos-rebuild --use-remote-sudo --file configuration.nix Recommended 🙂 1.a 1.b 2 🤑
  12. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  13. Freedom And Chaos Your configuration grows ➜ break it apart,

    use imports NixOS doesn't prescribe how to structure your repository Search for examples online (e.g. " ") nixos-config PEP 20 gitlab.com/painless-software/cicd/config/nixos Copier template
  14. Host-based Configuration hosts/ – managed machines roles/ – classes of

    machines (abstraction layer) system/ – system-global configuration home/ – user configuration user/ – common user configuration gitlab.com/painless-software/nixos-config
  15. Home Manager Manage user-specific software and settings ("dotfiles") standalone vs.

    NixOS module has own (most matching with nixpkgs) configuration options 💡 Some people use GNU Stow instead to manage dotfiles
  16. Disko Declarative disk partitioning “ disko-config.nix $ sudo nix run

    github:nix-community/disko/latest -- \ --mode destroy,format,mount \ --flake gitlab:painless-software/nixos-config#example
  17. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  18. The Nix Language { # numbers a = 1; f

    = 3.14; # strings text = "Hello Pi! ${f}"; multi_line = '' Very long text ... with ${a} ''; # boolean truth = false; lie = true; # attribute sets b = { foo = 1; bar = "something"; }; # lists c = [ 1 2 3 ]; d = [ "hello" "world" ]; # paths x = /absolute/path/to y = ./relative/path z = ~/.config # path in home dir } data types { # negation truth = !false; # string and paths a_str = "Dirs" + ~/.config/user-dirs.dirs; a_path = /etc + "/nixos"; # list concatenation l = [ 1 2 3 ] ++ [ "four" "five"]; # logical and, logical or m = true && false; n = true || false; # update attribute set s = { x = 1; } // { y = 1; x = 2; }; # has attribute (attribute set member) h = { x = 42; } ? x; } operators d = builtins.readDir; f = builtins.readFile; e = builtins.getEnv "HOME"; ... built-ins
  19. Nix File, Literals & Lambda 42 a.nix "foo" b.nix true

    c.nix ~/.local/bin d.nix [ ] e.nix { } f.nix x: x + 1 g.nix { x = import ./a.nix; } 1 2 3 imported.nix { lib, ... }: imports = [ ]; options = { }; config = { }; 1 2 { 3 4 5 6 my.option = lib.mkOption { }; 7 8 9 10 } 11 explicit.nix { console.keyMap = "it"; services.xserver.xkb = { layout = "it"; variant = ""; }; } 1 2 3 4 5 6 7 8 implicit-config.nix { lib, ... }: { options = { desktop.style = lib.mkOption { type = lib.types.enum [ "Windows" "macOS" "GNOME" ]; default = "GNOME"; }; }; } 1 2 3 4 5 6 7 8 9 10 options-only.nix ↷ “ Module
  20. Nix Module { lib, ... }: imports = [ ];

    options = { }; config = { }; 1 2 { 3 4 ./file.nix 5 6 7 8 magicNumber = lib.mkOption { 9 type = lib.types.number; 10 default = 3.14; 11 }; 12 13 14 15 boot.loader.grub.enable = true; 16 17 } 18 module.nix let foo = "Hello"; in default = foo; { lib, ... }: 1 2 3 4 5 { 6 imports = [ 7 ./file.nix 8 ]; 9 10 options = { 11 greeting = lib.mkOption { 12 type = lib.types.str; 13 14 }; 15 }; 16 17 config = { 18 boot.loader.grub.enable = true; 19 }; 20 } 21 variables.nix
  21. Nix Flake description = "Python Italia flake"; inputs = {

    outputs = { self, nixpkgs }: { { 1 2 3 4 nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; 5 nixos-hardware.url = "github:NixOS/nixos-hardware?ref=master"; 6 }; 7 8 9 nixosConfigurations = nixpkgs.lib.mapAttrs mkSystem systems; 10 }; 11 } 12 flake.nix $ nix flake update Recommendation
  22. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  23. Use Technology's QA Tools $ copier copy gl:painless-software/cicd/config/nixos nixos-config ...

    $ pre-commit install ... $ git init $ git add -v . ... $ pre-commit $ nix flake check ... --- deadnix: extends: .nix script: nix-shell -p deadnix --run "deadnix --fail" statix: extends: .nix script: nix-shell -p statix --run "statix check" flake: extends: .nix script: - nix flake check - nix flake show disko: extends: .nix script: nix run github:nix-community/disko/latest -- --mode destroy,format,mount --dry-run --flake .#generic tooling: extends: .megalinter variables: FLAVOR: documentation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .gitlab-ci.yml gitlab.com/painless-software/cicd/config/nixos Copier template
  24. Flake Establish execution entrypoint (e.g. integrate hosts/). Consider integrating QA

    tools, pre-commit and CI/CD early. 1. Iterative Development Home Manager Allow configuring settings and installing software for individual users. Consider using LDAP for a flexible, host- independent setup. 3. Disko Integrate Disko configuration. Verify installation process end-to-end. Consider setting up functional tests with VMs. 2. Refine Delegate host setup to system/ configuration. Consider introducing roles/. Consolitate home/ features in common user/ modules. 4.
  25. 2. Getting Started. Learning resources, downloads and basic commands. 1.

    Why use NixOS. Config management for Dev machines. 3. Repo Design. Beautiful is better than ugly. System and User configuration. 4. The Nix language. Modules and Lambda functions. 5. Develop your NixOS Config. Working with a tool you don't know yet. 6. Python on NixOS. Make development a breeze on a non- compliant system.
  26. Python on NixOS # system/software/developer.nix { pkgs, ... }: {

    environment.systemPackages = with pkgs; [ python313 # first in list will be default Python python312 python311 python310 uv ]; } 1 2 3 4 5 6 7 8 9 10 11 12 # system/software/developer.nix { pkgs, ... }: { environment.systemPackages = with pkgs; [ uv ]; } 1 2 3 4 5 6 7 8 a b system-managed $ uv python install --preview --default $ which python /home/nixos/.local/bin/python user-managed
  27. Cannot open shared object file $ uv venv Using CPython

    3.13.3 interpreter at: /run/current-system/sw/bin/python Creating virtual environment at: .venv $ source .venv/bin/activate $ uv pip install numpy + numpy==2.2.6 $ python >>> import numpy Traceback (most recent call last): ... ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory
  28. Uv Tool Interface $ uv tool install copier $ uv

    tool install httpie $ uv tool install pre-commit $ uv tool install pyclean $ uv tool install tox $ ls ~/.local/bin copier http httpie https pre-commit pyclean python tox $ uv tool list $ uv tool upgrade --all # system/terminal/default.nix { environment.localBinInPath = true; } 1 2 3 4
  29. Most backgrounds from Unsplash (CC BY-SA) Comic from Work Chronicles

    (CC BY-SA) Decorative icons are unicode (CC-0) Less pain, more fun.