1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-09-19 10:50:24 -04:00

reword the introduction in the manual

this is a very old text that focuses a lot on the how, although it
promises the what. the manual doesn't necessarily need this. but for the
sake of nostalgia, because it's nowhere else written down properly, and
because it still is and will likely stay an important entry point,
here's a careful rework.

it's focused on providing quick overview and encouraging readers to stick around.
This commit is contained in:
Valentin Gagarin 2024-01-29 05:26:31 +01:00
parent 40254092dd
commit a4fb087809

View file

@ -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 dont 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 (its a cryptographic hash of the
packages 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 dont 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 youre 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 doesnt 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 dont 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 dont 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 users `PATH`.
If a user installs a package that another user has already installed
previously, the package wont 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 users `$PATH`.
If a user installs a package that another user has already installed previously, the package wont 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 its 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 arent 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 arent 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 aret 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 isnt 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 arent 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 its a functional language, its 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 dont conflict with
each other in the Nix store.
This deletes all packages that arent 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
theyre 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 '<nixpkgs>' --attr pan
```
Which artifacts Nix produces is traditionally specified with _Nix expressions_.
Youre 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 **its a purely functional programming language**, it allows expressing highly complex compositions and their variants succinctly.
Since unique files have unique file system paths, variants wont 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).