devenv.sh
Fast, Declarative, Reproducible, and Composable Developer Environments
@domenkozar
fosstodon.org/@domenkozar
FOSDEM 2023
About me
-
2004: First installation of Linux: Gentoo
-
2012: Switched to NixOS
-
2014: Why Puppet/Chef/Ansible aren't good enough (and we can do better)
-
2018: cachix.org, free binary cache hosting for OSS
-
2020: nix.dev, Nix tutorials
-
2022: NixOS Foundation board member
-
2022: devenv.sh
Good defaults
macOS / Linux / WSL2
each config/package is pinned to a snapshot to all the inputs
automatically configures garbage collection
direnv.net integration
high-level abstraction over any tool
no need for containers
Declarative
$ cat devenv.nix
{ pkgs, ... }:
{
env.GREET = "determinism";
packages = [ pkgs.git ];
enterShell = "echo hello $GREET";
}
$ git --version
git: command not found
$ devenv shell
hello determinism
(devenv) $ git --version
git version 2.38.1
$ devenv search ncdu
...
Reproducible
$ cat devenv.yaml
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
Composable
$ cat devenv.yaml
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
devenv:
url: github:cachix/devenv
flake: false
imports:
- ./frontend
- devenv/examples/supported-languages
Fast
$ devenv ci
$ devenv shell
Building shell ...
Entering shell ...
(devenv) $
Files
- devenv.nix
- devenv.local.nix
- devenv.yaml
- devenv.lock
- .envrc
Garbage Collection
$ devenv gc
Counting old devenvs ...
Found 2097 store paths of sum size 9448 MB.
Garbage collecting ...
Note: If you'd like this command to run much faster,
leave a thumbs up at https://github.com/NixOS/nix/issues/7239
Languages
$ cat devenv.nix
{ pkgs, ... }:
{
languages.python.enable = true;
languages.python.venv.enable = true;
languages.typescript.enable = true;
}
36 supported languages and counting.
Rust
{ pkgs, lib, ... }:
{
packages = lib.optionals pkgs.stdenv.isDarwin [
pkgs.darwin.apple_sdk.frameworks.Security
];
languages.rust = {
enable = true;
version = "latest";
};
pre-commit.hooks = {
clippy.enable = true;
rustfmt.enable = true;
};
}
PHP
{ pkgs, lib, ... }:
{
languages.php = {
enable = true;
version = "latest";
};
}
{ pkgs, lib, ... }:
{
languages.php = {
enable = true;
version = "8.1";
ini = ''
memory_limit = 2G
'';
extensions = [ "redis" "amqp" ];
};
}
Processes
$ cat devenv.nix
{ pkgs, ... }:
{
processes = {
hello.exec = "while true; do echo hello && sleep 1; done";
ping.exec = "ping example.com";
};
}
$ devenv up
Starting processes ...
20:37:44 system | ping.1 started (pid=4094686)
20:37:44 system | silly-example.1 started (pid=4094688)
20:37:44 silly-example.1 | hello
20:37:44 ping.1 | PING example.com (93.184.216.34) 56(84) bytes of data.
20:37:44 ping.1 | 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=55 time=125 ms
20:37:45 silly-example.1 | hello
20:37:45 ping.1 | 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=55 time=125 ms
...
Services
$ cat devenv.nix
{ pkgs, lib, ... }:
{
services.caddy.enable = true;
services.redis.enable = true;
services.postgres.enable = true;
services.elasticsearch.enable = true;
services.mysql.enable = true;
}
Integrations: what if any tool could be a toggle?
$ cat devenv.nix
{ pkgs, ... }:
{
scripts."myscript".exec = ''
curl "https://httpbin.org/get?$1" | jq '.args'
'';
hosts."example.com" = "127.0.0.1";
devcontainer.enable = true;
difftastic.enable = true;
starship.enable = true;
}
Thanks! Get started:
domen@cachix.org / @domenkozar
https://devenv.sh
devenv.sh
By ielectric
devenv.sh
- 100