Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sandbox

Nimi provides a lightweight sandbox runner via mkBwrap. It uses bubblewrap to run your services in an isolated environment without requiring container runtimes like Docker or Podman.

What it provides

  • Isolated filesystem: A tmpfs-based root with selective host paths bound read-only.
  • Environment variables: Set via settings.bubblewrap.environment.
  • Working directory: Set via settings.bubblewrap.chdir.
  • Namespace isolation: Separate user, PID, UTS, IPC, and cgroup namespaces by default.
  • Writable directories: /tmp, /run, /var, /etc are tmpfs mounts for runtime writes.
  • Nix store access: /nix/store is bind-mounted read-only so binaries can access their dependencies.

Minimal example

pkgs.nimi.mkBwrap {
  services."my-app" = {
    process.argv = [ (lib.getExe pkgs.my-app) ];
  };
  settings.bubblewrap = {
    environment.MY_VAR = "value";
    chdir = "/app";
    extraTmpfs = [ "/data" ];
  };
}

Run the sandbox:

nix run .#my-sandbox

Extended example

pkgs.nimi.mkBwrap {
  services."web-server" = {
    process.argv = [ (lib.getExe pkgs.nginx) "-g" "daemon off;" ];
  };
  settings.bubblewrap = {
    environment = {
      APP_ENV = "production";
      LOG_LEVEL = "info";
    };
    chdir = "/srv";
    roBinds = [
      { src = "/nix/store"; dest = "/nix/store"; }
      { src = "/etc/ssl"; dest = "/etc/ssl"; }
      { src = "/run/secrets"; dest = "/secrets"; }
    ];
    extraTmpfs = [ "/var/cache/nginx" ];
  };
}

How it works

  1. Build time: The nimi binary is wrapped in a shell script that invokes bwrap.
  2. Execution: bwrap runs the nimi binary inside an isolated namespace with:
    • Tmpfs mounts created first (providing writable areas)
    • Read-only bind mounts layered on top (e.g., /nix/store over /nix)
    • /dev and /proc bound from the host
    • Environment variables and working directory applied
    • Namespaces unshared according to configuration

Differences from containers

FeaturemkBwrapmkContainerImage
Runtime dependenciesbubblewrap onlyContainer runtime (Docker, Podman)
Image formatNone (uses Nix store directly)OCI image
Startup timeFast (no image loading)Depends on runtime
PortabilityLinux onlyAny OCI-compatible runtime
Base imagesNot supportedSupported via fromImage
Root filesystemTmpfs with bind mountsLayered image filesystem

Notes

  • The sandbox requires Linux with user namespaces enabled.
  • Writes go to tmpfs directories; they are lost when the sandbox exits.
  • Signal handling (Ctrl+C) is supported.
  • The entrypoint is always the generated nimi runner from mkNimiBin.
  • Not available on macOS (meta.badPlatforms includes Darwin).