2023-05-11 - Learning Journey Working Group - Meeting Notes #8
- Previous meeting notes
- Attendees: @zmitchell @khaled @henrik-ch @infinisil @Jeremiah
- Notes taken by: @henrik-ch
Review of what we decided for the tutorial series last time
- Python web server
- Postgres database
- set up Python dependencies in nixpkgs
- set up NixOS tests
- integration tests using Nix-only facilities
Identifying first steps of the journey
-
@zmitchell - First step: nix-shell -p tutorial
- this can be our first iteration of the webapp
- single python file with a hello world app using Python standard library
-
@zmitchell - Second step: shell.nix with no new dependencies
- Verify that the webserver runs using the Python defined in shell.nix
-
@Jeremiah sounds like a good starting point - shall we introduce conscious errors?
- @zmitchell - might be a cognitive overload on the beginner user
When to teach the Nix language
-
@zmitchell - is this the point where we teach nix language and pinning?
- @infinisil - mention that the nix language is used - and direct them to tutorial if interested - but not making it a requirement to move further.
- @zmitchell - @fricklerhandwerk added a flowchart for sequencing, see below
-
@infinisil - introduce shell.nix, introduce language incrementally, and itās also not a problem to say nix language is a requirement to continue.
- @khaled - we teach enough nix language as we go, right? we donāt want to stop the whole tutorial to deep dive in the language tutorial?
- @infinisil - function calls, lists, attribute set declarations, lambdas? - the list gets extensive quite quickly.
-
@Jeremiah - could it be alongside? not breaking it down - but more linking it from the shell.nix file?
- @infinisil - (see example below) - can we link to nix.dev and reference manual in comments?
- @infinisil - on nix.dev - we can add a more direct reference to the reference manual
- @zmitchell & @khaled - we might have a formatting problem - how to make clickable links on our language snippet
- @zmitchell first shell.nix should be as minimal as possible - difficult to distinguish import syntax parts - noisy
-
@zmitchell - alternative - give the user a shell.nix with python - you donāt need to understand it yet. Then in the next tutorial use this shell.nix as an example for explaining the Nix language.
- @Jeremiah - this may be helpful
- @Jeremiah - beginners look at the language - and they canāt see the correlations - what is a function inside a shell et cetera.
Contents of shell.nix tutorial
-
@zmitchell - introducing the Nix language after shell.nix tutorial means shell.nix tutorial is left with little content
- @zmitchell - can we enrich it without introducing additional concepts?
-
@infinisil - can we introduce the pinning? it helps for reproducibility - but demands pinning skills
- @zmitchell - pinning is a later step
- @infinisil suggesting first depending on the NIX_PATH, and then move to a pinned example
- @Jeremiah this means we start out in a non-gradual way? you show the granularity that nix can provide in steps, rather than starting with the full details.
- @infinisil start using nixpkgs with shell.nix - next is github branch - you can fetch expressions using nix
- @zmitchell - thinking channels inside pinning parts - like an intermediate step?
- @infinisil - different levels of nix purity - evaluation, runtime & more
- @zmitchell - when we do pinning do we add the nixpkgs aspect?
-
@zmitchell - idea about the env variable in the example
- Set an environment variable in shell.nix
- Use the environment variable in the Python web server
- Now the user sees how to configure the behavior of their server declaratively with Nix
-
@infinisil - nix tutorial is not a prerequisite (yet)
- @infinisil - if people feel confused, it makes them motivated to read the nix lang tutorial to keep up
- @Jeremiah - shell.nix tutorial - because it hasnāt been in depth explained - as a new user they are motivated to continue
-
@infinisil - you can put the shell hook stuff in the --run on the nix-shell -p command
- @infinisil you can add exports to the shell hook
- @zmitchell we add environment variable from the start - maybe we leave it out from the nix-shell -p initial example
-
@zmitchell - letās recap the steps weāve figured out
- nix-shell -p - small server standard python
- shell.nix tutorial - minimal env customization
- nix language - explain the shell.nix we made
- Evaluation purity
- non pinned fetching, link to something channels (how published - pushed to branches etc.)
- introduce pinning - pinned fetching, mention prefetchers, niv and flakes - just as links/pointers
- system, config, overlays
Adding Python dependencies
- @zmitchell - reader needs to find flask
- @infinsil - now we need a builder from nixpkgs.
-
@zmitchell incremental approach - add flask to shell and get it running
- flask has a CLI for running the app, no issues with PYTHONPATH
- @zmitchell the derivation may complicate things
- @infinisil flask is under python packages
-
@infinisil: How about
pkgs.python3Packages.buildPythonApplication
, but not building it yet, just using it as a shell instead ofmkShell
. - @zmitchell - if we abandon pkgs.mkshell fo buildPythonApplication we need to justify why we make the switch
- @zmitchell - we could add a library, not a binary, to demonstrate the value of the python builder vs the mkshell.
- @Jeremiah - or a postgres integration
- @infinisil - a stepwise approach, buidling the python package as passing it along into the shell environment
- @Jeremiah - we are looking for an iterative process
- @khaled - start with a simpler default.nix
- @infinisil - Move towards this pattern for building
mkShell {
buildInputs = [
python3Packages.flask
]
}
=>
let
myPackage = python3Packages.buildPythonApplication {
propagatedBuildInputs = [
python3Packages.flask
];
};
in myPackage // {
shell = mkShell {
inputsFrom = [
myPackage
];
buildInputs = [
curl
];
};
}
# shell.nix
(import ./default.nix).shell
-
@zmitchell - how to explain what Nixpkgs is?
- @infinisil - Packages, package search
- @infinisil - The library, non-derivation creating
- @infinisil - Derivation-creating functions, fetchers, builders
-
@henrik-ch: Do you need the structure for pinning?
- @zmitchell: Not for using but if you wanna look at expressions
-
@infinisil: pkgs.hello.meta.position,
nix edit -f '<nixpkgs>' hello
- Package search contains a link to the source
-
@infinisil: Package search would be useful even before nix-shell -p
-
@Jeremiah: Refer to the search afterwards when needing new packages for repetition
-
Letās stick with online package search, no CLI because it sucks currently
-
@infinisil: Also later the
nix repl
is introduced, auto-completion
-
@infinisil: Also later the
Example of an annotated Nix file (letās not do this)
# shell.nix
{ # Function argument declaration (link to https://nix.dev/tutorials/first-steps/nix-language#functions)
pkgs ? # Function default ...
import
(fetchTarball "https://github.com/NixOS/nixpkgs/archive/06278c77b5d162e62df170fec307e83f1812d94b.tar.gz")
{},
}:
pkgs.mkShell {
buildInputs = [
pkgs.which
pkgs.htop
pkgs.zlib
];
}
Knowledge graph
flowchart
lang[Nix language] --> shell[shell.nix] & drv[declaring derivations]
drv --> python[Python packaging]
pinning[pinning Nixpkgs]
lang --> modules[module system]
modules --> config[declarative configurations]
shell & config --> devenv[development environments]
config & testing[NixOS testing framework] --> vmTests[NixOS VM tests]
pinning & lang --> reproducible[reproducible builds]