diff --git a/doc/manual/src/introduction.md b/doc/manual/src/introduction.md index 76489bc1b..02a51d61e 100644 --- a/doc/manual/src/introduction.md +++ b/doc/manual/src/introduction.md @@ -1,193 +1,144 @@ -# Introduction +# Welcome to Nix -Nix is a _purely functional package manager_. This means that it -treats packages like values in purely functional programming languages -such as Haskell — they are built by functions that don’t have -side-effects, and they never change after they have been built. Nix -stores packages in the _Nix store_, usually the directory -`/nix/store`, where each package has its own unique subdirectory such -as +# Where Nix comes from - /nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/ +Nix was created by Eelco Dolstra and developed as the subject of his PhD thesis [The Purely Functional Software Deployment Model](https://edolstra.github.io/pubs/phd-thesis.pdf), published 2006. +Over the years, many others have joined the effort to make software work reliably, now and in the long run. +Today, a [world-wide developer community](https://nixos.org/) contributes to Nix and the ecosystem that has grown around it. -where `b6gvzjyb2pg0…` is a unique identifier for the package that -captures all its dependencies (it’s a cryptographic hash of the -package’s build dependency graph). This enables many powerful -features. +# How Nix works -## Multiple versions +> The name *Nix* is derived from the Dutch word *niks*, meaning *nothing*; +> build actions do not see anything that has not been explicitly declared as an input. +> +> — [Nix: A Safe and Policy-Free System for Software Deployment](https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf), LISA XVIII, 2004 -You can have multiple versions or variants of a package -installed at the same time. This is especially important when -different applications have dependencies on different versions of the -same package — it prevents the “DLL hell”. Because of the hashing -scheme, different versions of a package end up in different paths in -the Nix store, so they don’t interfere with each other. +Nix primarily deals with making sure that files are complete and available when processes need them. +This is accomplished by two measures: +- All files and their relations are specified by cryptographic hash in the Nix store, and are made immutable. + Files are only deleted when nothing refers to them any more. + This guarantees that a successful program run can be repeated, because nothing will change or disappear inadvertently. +- Processes are executed in a clean environment, where they can only access what is explictly allowed. + This prevents obtaining useful results without specifyig all dependencies. -An important consequence is that operations like upgrading or -uninstalling an application cannot break other applications, since -these operations never “destructively” update or delete files that are -used by other packages. +Nix has become known as the *purely functional package manager*, because this approach to ensure repeatability allows escaping from [dependency hell](https://en.wikipedia.org/wiki/Dependency_hell) and taming the complexity of the software ecosystem. +It is grown an ecosystem of exceptionally powerful tools – including Nixpkgs, , and NixOS, a Linux distribution that can be configured fully declaratively, with unmatched flexibility. -## Complete dependencies +At the heart of this is the [Nix store](./store/index.md). +It keeps immutable file system objects, and tracks dependencies between them. +It can also execute sandboxed processes and efficiently copy bundled dependencies across machines in a way that preverves correctness. -Nix helps you make sure that package dependency specifications are -complete. In general, when you’re making a package for a package -management system like RPM, you have to specify for each package what -its dependencies are, but there are no guarantees that this -specification is complete. If you forget a dependency, then the -package will build and work correctly on _your_ machine if you have -the dependency installed, but not on the end user's machine if it's -not there. +Nix comes with a purely functional programming language to describe and compose these computations, and succinctly refer to their inputs and outputs: the [Nix language](./language/index.html). -Since Nix on the other hand doesn’t install packages in “global” -locations like `/usr/bin` but in package-specific directories, the -risk of incomplete dependencies is greatly reduced. This is because -tools such as compilers don’t search in per-packages directories such -as `/nix/store/5lbfaxb722zp…-openssl-0.9.8d/include`, so if a package -builds correctly on your system, this is because you specified the -dependency explicitly. This takes care of the build-time dependencies. +# What Nix can do -Once a package is built, runtime dependencies are found by scanning -binaries for the hash parts of Nix store paths (such as `r8vvq9kq…`). -This sounds risky, but it works extremely well. +Nix enforces *complete, exact* dependencies whenever software under its control is run. +This makes possible unique features without compromising on efficiency. + +## Multiple software versions side by side + +You can have multiple versions or variants of a package installed at the same time. +Different files always end up on different paths in the Nix store, so they don’t interfere with each other. +This circumvents the “DLL hell”. + +An important consequence is that upgrading or uninstalling an application cannot break other applications, since these operations never “destructively” update or delete files that are used otherwise. ## Multi-user support -Nix has multi-user support. This means that non-privileged users can -securely install software. Each user can have a different _profile_, -a set of packages in the Nix store that appear in the user’s `PATH`. -If a user installs a package that another user has already installed -previously, the package won’t be built or downloaded a second time. -At the same time, it is not possible for one user to inject a Trojan -horse into a package that might be used by another user. +Nix has multi-user support. +This means that non-privileged users can securely install software. +Each user can have a different _profile_, a set of programs in the Nix store that appear in the user’s `$PATH`. +If a user installs a package that another user has already installed previously, the package won’t be built or downloaded a second time. +At the same time, it is not possible for one user to inject a Trojan horse into a package another user may rely on. ## Atomic upgrades and rollbacks -Since package management operations never overwrite packages in the -Nix store but just add new versions in different paths, they are -_atomic_. So during a package upgrade, there is no time window in -which the package has some files from the old version and some files -from the new version — which would be bad because a program might well -crash if it’s started during that period. +Since files in the Nix store are never changed, new versions are added to different paths, and environments are constructed from symlinks to these paths. -And since packages aren’t overwritten, the old versions are still -there after an upgrade. This means that you can _roll back_ to the -old version: +Swapping symlinks to paths is _atomic_. +With Nix, during a software upgrade, there is no time window in which a package has some files from the old version and some files from the new version. +This eliminates inconsistencies by construction. -```console -$ nix-env --upgrade --attr nixpkgs.some-package -$ nix-env --rollback -``` +And since files aren’t overwritten, the old versions are still there after an upgrade. +This means that you can instantly _roll back_ to an old version. ## Garbage collection -When you uninstall a package like this… +Files are’t deleted from the system right away — after all, you might want to do a rollback, or they might be in the profiles of other users. +Instead, unused packages can be deleted safely by running the _garbage collector_. -```console -$ nix-env --uninstall firefox -``` - -the package isn’t deleted from the system right away (after all, you -might want to do a rollback, or it might be in the profiles of other -users). Instead, unused packages can be deleted safely by running the -_garbage collector_: - -```console -$ nix-collect-garbage -``` - -This deletes all packages that aren’t in use by any user profile or by -a currently running program. - -## Functional package language - -Packages are built from _Nix expressions_, which is a simple -functional language. A Nix expression describes everything that goes -into a package build task (a “derivation”): other packages, sources, -the build script, environment variables for the build script, etc. -Nix tries very hard to ensure that Nix expressions are -_deterministic_: building a Nix expression twice should yield the same -result. - -Because it’s a functional language, it’s easy to support -building variants of a package: turn the Nix expression into a -function and call it any number of times with the appropriate -arguments. Due to the hashing scheme, variants don’t conflict with -each other in the Nix store. +This deletes all packages that aren’t in use by a currently running program or otherwise. ## Transparent source/binary deployment -Nix expressions generally describe how to build a package from -source, so an installation action like +Nix expressions generally describe how to build software from source, starting from some initial binary that is taken for granted. +This is a _source deployment model_. -```console -$ nix-env --install --attr nixpkgs.firefox -``` +But since outputs are cached, building is only required if the output in question are not already in the Nix store. +Nix can also automatically skip building from source and instead use a _binary cache_, a web server that provides pre-built binaries. +This is a _binary deployment model_. -_could_ cause quite a bit of build activity, as not only Firefox but -also all its dependencies (all the way up to the C library and the -compiler) would have to be built, at least if they are not already in the -Nix store. This is a _source deployment model_. For most users, -building from source is not very pleasant as it takes far too long. -However, Nix can automatically skip building from source and instead -use a _binary cache_, a web server that provides pre-built -binaries. For instance, when asked to build -`/nix/store/b6gvzjyb2pg0…-firefox-33.1` from source, Nix would first -check if the file `https://cache.nixos.org/b6gvzjyb2pg0….narinfo` -exists, and if so, fetch the pre-built binary referenced from there; -otherwise, it would fall back to building from source. +[Hydra](https://hydra.nixos.org/), the Nix build cluster, has been producing binary artifacts and making them available in the [public cache](http://cache.nixos.org/) for many years. +The cache allows running software going back as far as 2010, especially where sources cannot be obtained otherwise any more. -## Nix Packages collection +Nix also makes it easy to set up your own binary cache. -We provide a large set of Nix expressions containing hundreds of -existing Unix packages, the _Nix Packages collection_ (Nixpkgs). +## Distributed builds -## Managing build environments +Nix can **transparently delegate tasks to remote machines**, for example to build on different architectures or operating systems, or run many builds in parallel. +These machines can share the same cache. -Nix is extremely useful for developers as it makes it easy to -automatically set up the build environment for a package. Given a Nix -expression that describes the dependencies of your package, the -command `nix-shell` will build or download those dependencies if -they’re not already in your Nix store, and then start a Bash shell in -which all necessary environment variables (such as compiler search -paths) are set. +Setting up your own remote build machine only requires installing Nix (or NixOS), registering SSH keys, and configuring the client when to use it. -For example, the following command gets all dependencies of the -Pan newsreader, as described by [its -Nix expression](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix): +## Functional configuration language -```console -$ nix-shell '' --attr pan -``` +Which artifacts Nix produces is traditionally specified with _Nix expressions_. -You’re then dropped into a shell where you can edit, build and test -the package: +A Nix expression describes everything that goes into a “derivation”: +the executable to run, input files and environment variables it can read, and command line arguments. -```console -[nix-shell]$ unpackPhase -[nix-shell]$ cd pan-* -[nix-shell]$ configurePhase -[nix-shell]$ buildPhase -[nix-shell]$ ./pan/gui/pan -``` +Nix tries very hard to ensure that **Nix expressions are deterministic**: +both evaluating the Nix expression and running an executable configured that way should yield the same result every time. -## Portability +Because **it’s a purely functional programming language**, it allows expressing highly complex compositions and their variants succinctly. +Since unique files have unique file system paths, variants won’t conflict with each other in the Nix store. -Nix runs on Linux and macOS. +## Nixpkgs software distribution -## NixOS +[Nixpkgs](https://github.com/NixOS/nixpkgs) has become [the largest, most up-to-date free software repository in the world](https://repology.org/repositories/graphs). +It holds tens of thousands of working packages **built from source** and **instantly available in binary form**. +It offers mechanisms to **compose or customise software** according to your needs. -NixOS is a Linux distribution based on Nix. It uses Nix not just for -package management but also to manage the system configuration (e.g., -to build configuration files in `/etc`). This means, among other -things, that it is easy to roll back the entire configuration of the -system to an earlier state. Also, users can install software without -root privileges. For more information and downloads, see the [NixOS -homepage](https://nixos.org/). +## NixOS Linux distribution -## License +[NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos) is a Linux distribution based on Nix and Nixpkgs, and allows you to **manage the entire system configuration declaratively** through the Nix language. + +This means, among other things, that it is easy to configure settings for all programs and services uniformly, and recreate them any time from a text file, by rolling back to an earlier state, deploying it directly to remote machines, or building containers and virtual machines efficienly. + +## Cross-platform + +Nix is written in C++. +It runs on Linux, macOS, and WSL, and is compiled for many common CPU architectures. + +# How to use Nix + +This is the reference manual for Nix: it documents the Nix store, the Nix language, the command line interface, and formats, protocols, and APIs Nix supports. +It is intended for looking up facts and precise details. +Here is the place where information about Nix is most likely to be correct. + +Reading it “back to back” is certainly not the quickest or easiest way to learn how to use Nix. +But it is a reliable path to gain a solid understanding of the sytem. +Your feedback on any aspect of this manual is appreciated and will help us make it better. + +If you want to get things done quickly, visit [nix.dev](https://nix.dev) for [beginner tutorials](https://nix.dev/tutorials/first-steps). + +If you want to know how the full truth, get the [source code on GitHub](https://github.com/NixOS/nix). + +## How to help + +Check the [contributing guide](https://github.com/NixOS/nix) if you want to get involved with developing Nix. + +# License + +Nix is released under the terms of the [GNU LGPLv2.1 or (at your option) any later version](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html). -Nix is released under the terms of the [GNU LGPLv2.1 or (at your -option) any later -version](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html).