1
0
Fork 0
mirror of https://github.com/NixOS/nix.dev.git synced 2024-10-18 14:32:43 -04:00

Merge pull request #256 from worktheclock/patch-6

This commit is contained in:
Valentin Gagarin 2023-06-27 20:33:06 +02:00 committed by GitHub
commit 924b25d2ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,31 +2,23 @@
# Declarative and reproducible developer environments
In the {ref}`ad-hoc-envs` tutorial we looked at providing shell
environments for when we need a quick'n'dirty way of getting hold
of some tools.
In the {ref}`ad-hoc-envs` tutorial, we looked at imperatively creating shell environments using `nix-shell -p`, for when we need a quick way to access some tools without having to install them globally. We also saw how to execute that command with a specific nixpkgs git commit as an argument, to recreate the same environment used previously.
In this tutorial we'll take a look how to create {term}`reproducible`
shell environments given a declarative configuration file called a Nix expression.
In this tutorial, we'll see how to *declaratively* create {term}`reproducible` shell environments using a configuration file called a Nix expression.
## When are declarative shell environments useful?
This is the quickest approach to getting started with Nix:
Both methods of creating development shell environments allow you to provide CLI tools like `psql`, `jq`, and `tmux`, as well as developer libraries like `zlib` and `openssl`. However, only the *declarative* approach allows you to
- use single command to invoke it via `nix-shell`
- it works across different operating systems (Linux / MacOS)
- you share the exact same environment with all developers
- automatically set shell environment variables,
- execute bash commands during environment activation, and
- share the exact same environment with other developers.
Developer environments allow you to:
- provide CLI tools, such as `psql`, `jq`, `tmux`, etc
- provide developer libraries, such as `zlib`, `openssl`, etc
- set shell environment variables
- execute bash during environment activation
In addition to these, declaring development environments in Nix expression files enables you to use all the source code workflows you're used to, like committing that file to version control, using code analysis tools, and so on.
## Getting started
At the top-level of your project create `shell.nix` with the following contents:
At the top-level of your project, create `shell.nix` with the following contents:
```nix
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/06278c77b5d162e62df170fec307e83f1812d94b.tar.gz") {} }:
@ -41,12 +33,12 @@ pkgs.mkShell {
```
:::{note}
To understand the first line, read through {ref}`pinning nixpkgs tutorial <ref-pinning-nixpkgs>`.
To better understand the first line, read through the tutorial on {ref}`pinning nixpkgs <ref-pinning-nixpkgs>`.
:::
We import `nixpkgs` and make a shell with `which` and `htop` available in `$PATH`.
`zlib` provides libraries and headers in case we're compiling something against it.
To enter the environment:
This expression imports `nixpkgs`, then creates a shell with `which` and `htop` available in `$PATH`. `zlib` is also added, to provide some common libraries and headers in case we need to compile something against it.
To enter the environment, run `nix-shell` in the same directory as `shell.nix`:
```shell-session
$ nix-shell
@ -57,16 +49,13 @@ copying path '/nix/store/072a6x7rwv5f8wr6f5s1rq8nnm767cfp-htop-2.2.0' from 'http
[nix-shell:~]$
```
The command will start downloading the missing packages from the <https://cache.nixos.org> binary cache.
This command will start downloading the missing packages from the <https://cache.nixos.org> binary cache.
Once it's done, you are dropped into a new
shell. This shell provides the packages specified in `shell.nix`.
Once the download completes, you are dropped into a new shell, which provides the packages specified in `shell.nix`.
Run `htop` to confirm that it is present. Quit the program by hitting
`q`.
Run `htop` to confirm that it is present. Quit the program by hitting `q`.
Now, try `which htop` to check where the `htop` command is on disk.
You should see something similar to this:
Now try `which htop` to check where the `htop` executable is stored in the filesystem. You should see something similar to this:
```shell-session
[nix-shell:~]$ which htop
@ -75,7 +64,8 @@ You should see something similar to this:
## Customizing your developer environment
Given the following `shell.nix`:
We may want to run some commands whenever we enter the environment, for example echoing a message to the console. We may also want to set some variables that are only present within the environment.
To accomplish these, we can modify the `shell.nix` from the previous section like so:
```nix
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/06278c77b5d162e62df170fec307e83f1812d94b.tar.gz") {} }:
@ -105,29 +95,27 @@ hello
world
```
- The `shellHook` section allows you to execute bash while entering the shell environment.
- The `shellHook` section allows you to execute bash commands while entering the shell environment.
- Any attributes passed to `mkShell` function are available once the shell environment is active.
## `direnv`: Automatically activating the environment on directory change
Besides activating the environment for each project, every time you change
`shell.nix` you need to re-enter the shell.
In addition to manually activating the environment for each project, you need to re-enter the shell every time you change `shell.nix`.
You can use `direnv` to automate this process for you, with the downside that each developer needs
to install it globally.
You can use `direnv` to automate this process for you, with the tradeoff that each developer using the environment needs to install it globally.
### Setting up `direnv`
1. [Install nix-direnv with your package manager or from source](https://github.com/nix-community/nix-direnv)
2. [Hook it into your shell](https://direnv.net/docs/hook.html)
At the top-level of your project run:
From the top-level directory of your project run:
```shell-session
$ echo "use nix" > .envrc && direnv allow
```
The next time your launch your terminal and enter the top-level of your project direnv will check for changes.
The next time you launch your terminal and enter the top-level directory of your project, `direnv` will check for changes to the `shell.nix` file.
```shell-session
$ cd myproject
@ -138,6 +126,5 @@ hello
## Next steps
- {ref}`pinning-nixpkgs` to see different ways to import nixpkgs
- To quickly set up a Nix project read through
[Getting started Nix template](https://github.com/nix-dot-dev/getting-started-nix-template).
- Take a look at our {ref}`pinning-nixpkgs` tutorial to see different ways to import Nixpkgs.
- To quickly set up a Nix project, read [Getting started Nix template](https://github.com/nix-dot-dev/getting-started-nix-template).