Skip to content

Validate identical dev/prod environments

Background

In order to verify that your development environment matches the production environment you can examine the Nix store path of the environment in both locations.

The Nix store is a directory that serves as a cache of all the programs, libraries, scripts, etc in your environment. Paths in this directory have the form /nix/store/<hash>-<name>, where the hash is used to uniquely identify the package. The hash in the path is computed from the hashes of all the package dependencies, the system (CPU architecture and OS), and the source of the package itself, so a change in any of these will result in a different store path.

Compare store paths

Lets create our demo environment.

$ flox create -e demo
...
created environment demo (...)

Each generation of an environment has its own path. Start by getting the current path for your environment:

$ tracelinks $(flox list --json -e demo | jq -r .path) # (1)!
...
/.../.local/share/flox/environments/local/....demo -> ....demo-1-link
  /.../.local/share/flox/environments/local/....demo-1-link -> /nix/store/...-floxShell
    /nix/store/...-floxShell -> /nix/store/...-wrapper
      /nix/store/...-wrapper: directory # (2)!
  1. flox list --json dumps metadata about an environment, and we filter with jq to just keep the path of the environment. tracelinks follows symlinks until it finds an actual file or directory.
  2. flox environments are wrapped in a few layers of symlink indirection, but all the symlinks can be ignored for the purpose of this how-to

You can run this same command in your production environment, and as long as the CPU architecture and OS are the same you should get the same path.

Now add a package to your development environment:

$ flox install -e demo ripgrep
...
Installed 'ripgrep' package(s) into 'demo' environment.

Now get the new path for your environment and see that they are different:

$ tracelinks $(flox list --json -e demo | jq -r .path)
...
/.../.local/share/flox/environments/local/....demo -> ....demo-2-link
  /.../.local/share/flox/environments/local/....demo-2-link -> /nix/store/...-floxShell
    /nix/store/...-floxShell -> /nix/store/...-wrapper
      /nix/store/...-wrapper: directory # (1)!

  1. The environment store path changed.

If you rollback to a prior generation, your environment will have the original path again:

$ flox rollback -e demo
...
Rolled back environment 'demo' from generation 2 to 1.

$ tracelinks $(flox list --json -e demo | jq -r .path)
...
/.../.local/share/flox/environments/local/....demo -> ....demo-1-link
  /.../.local/share/flox/environments/local/....demo-1-link -> /nix/store/...-floxShell
    /nix/store/...-floxShell -> /nix/store/...-wrapper
      /nix/store/...-wrapper: directory

From this exercise you can now see that a given generation of an environment on a given CPU architecture and OS will always be the same, and this can be verified by checking the underlying store path.