devenv.sh

 

Fast, Declarative, Reproducible, and Composable Developer Environments using Nix

Sander, Domen

Cachix @ NixCon 2024

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
...

Declarative

$ cat devenv.nix 
{ pkgs, ... }: {
  languages.ruby = {
    enable = true;
    version = "3.3.5";
    bundler.enable = true;
  };
}
$ devenv shell
(devenv) $ ruby -v
ruby 3.3.5 (2024-09-03 revision ef084cc8f4)
[x86_64-linux]

supports 54 languages

Processes

$ cat devenv.nix 
{ pkgs, ... }:

{
  processes = {
    hello.exec = "while true; do echo hello && sleep 1; done";
    ping.exec = "ping example.com";
  };
}

Scripts & Tasks

{ pkgs, ... }: {
  tasks = {
    "myapp:build" = {
       exec = "build";
       before = [ "devenv:enterShell" ];
    };
  };
  
  scripts.build.exec = "yarn build";
}
{ pkgs, ... }: {
  # Runs on `git commit` and `devenv test`
  pre-commit.hooks = {
    black.enable = true;
    # Your custom hooks
    generate-css = {
      enable = true;
      name = "generate-css";
      entry = "build";
    };
  };
 }

git hooks

Services

$ cat devenv.nix
{ pkgs, ... }:

{
  services.postgres = {
    enable = true;
    package = pkgs.postgresql_15;
    initialDatabases = [{ name = "mydb"; }];
    extensions = extensions: [
      extensions.postgis
      extensions.timescaledb
    ];
    settings.shared_preload_libraries = "timescaledb";
    initialScript = "CREATE EXTENSION timescaledb;";
  };
}

supports 33 services

$ devenv test

{ pkgs, ... }: {
  services.postgres = {
    enable = true;
    package = pkgs.postgresql_15;
    initialDatabases = [{ name = "mydb"; }];
    extensions = extensions: [
      extensions.postgis
      extensions.timescaledb
    ];
    settings.shared_preload_libraries = "timescaledb";
    initialScript = "CREATE EXTENSION IF NOT EXISTS timescaledb;";
  };
  
  processes.docs.exec = "${pkgs.mkdocs}/bin/mkdocs serve";

  enterTest = ''
    wait_for_port 8000
    curl http://localhost:8000 | grep "Hello, world!"
  '';
}

Thanks! Join discord:

domen@cachix.org / @domenkozar

devenv.sh workshop

By ielectric

devenv.sh workshop

  • 99