Skip to content

eliappo/rpi-dotfiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reproducible Environments with Nix

This repository uses the Nix package manager to declaratively define two things:

  1. A personal user environment (dotfiles repo) — tools always available on the machine
  2. A benchmarking environment (research-project repo) — tools available only when doing benchmarking work

The key benefit: anyone can reproduce the exact same environment on any Linux machine with Nix installed, regardless of what OS is running.


Why Nix?

Traditional package managers like apt or brew are imperative and implicit — you run commands over time and the system ends up in some state that is hard to reproduce. If you set up a machine six months ago you probably cannot remember exactly what you installed or which versions you used.

Nix is declarative and explicit — you describe what you want in a file, and Nix produces exactly that. The same file on a different machine produces an identical environment, including exact package versions. This is especially useful when:

  • Moving a benchmarking setup from a Raspberry Pi to an HPC cluster
  • Onboarding a collaborator who needs the exact same toolchain
  • Reproducing results on a different machine months later

Repository Structure

~/dotfiles/ — Personal User Environment

dotfiles/
├── flake.nix   # entry point, pins exact versions of everything
├── flake.lock  # auto-generated lock file, do not edit manually
├── home.nix    # top-level user config, lists installed packages
└── bash.nix    # shell config, aliases, direnv integration

~/research-project/ — Benchmarking Environment

research-project/
├── flake.nix   # defines the benchmarking shell environment
├── flake.lock  # pins exact versions
└── .envrc      # tells direnv to auto-activate the environment

File Explanations

flake.nix

The entry point for Nix. It has two parts:

inputs — declares where packages come from and pins them to a specific revision of nixpkgs (the Nix package repository, which contains over 100,000 packages).

outputs — declares what this flake produces. In the dotfiles repo this is a homeConfigurations output (a user environment). In the research-project repo this is a devShells output (a temporary shell with benchmarking tools).

flake.lock

Auto-generated by Nix the first time you run any nix command. It records the exact git commit hash of every input, ensuring that running the flake today produces the same result as running it in six months. Always commit this file.

home.nix

Declares which packages are always available in the user's environment. This is analogous to a list of apt install commands, but declarative — removing a package from this file and running home-manager switch will uninstall it.

home.packages = with pkgs; [
  git
  neovim
  tmux
  bat     # better cat
  eza     # better ls
];

bash.nix

Configures the bash shell declaratively, including:

  • direnv — automatically activates the benchmarking environment when you cd into the project directory
  • zoxide — smarter cd that learns your most visited directories
  • shellAliases — replaces common tools with better alternatives (catbat, lseza)

research-project/flake.nix

Defines the benchmarking shell environment. Running nix develop inside this directory gives you a shell with exactly these tools at exactly these versions:

packages = with pkgs; [
  jdk21
  gradle
  perf
  linuxPackages.cpupower
];

The prompt changes to [Bench-Marking-Shell] when the environment is active so you always know which context you are in.


How to Use

First-time setup on a new machine

  1. Install Nix:

    sh <(curl -L https://nixos.org/nix/install) --daemon
  2. Enable flakes (add to /etc/nix/nix.conf):

    experimental-features = nix-flakes nix-command
    
  3. Clone the dotfiles repo and activate:

    git clone <repo> ~/dotfiles
    nix run home-manager -- switch --flake ~/dotfiles#elias
  4. Open a new shell session. All tools from home.nix are now available.

Entering the benchmarking environment

If you have set up the dotfiles (which includes direnv), entering the project directory is enough:

cd ~/research-project
# environment activates automatically
gradle jmh

Or manually without direnv:

cd ~/research-project
nix develop

Updating packages

# update all inputs to their latest versions
nix flake update

# re-activate to apply changes
home-manager switch --flake ~/dotfiles#elias  # for dotfiles
nix develop                                    # for research-project

Porting to a New Machine (e.g. the Spark HPC cluster)

Because everything is pinned in flake.lock, porting is just:

  1. Install Nix and enable flakes (same as above)
  2. Clone the repo
  3. Run nix develop

The benchmarking environment on the Spark machine will be bit-for-bit identical to the one on the Raspberry Pi — same JDK version, same Gradle version, same everything. No "works on my machine" problems.

If the Spark machine uses a different CPU architecture (e.g. x86_64 instead of aarch64), the system variable in flake.nix needs to match. This is the only change required.

About

Nix configuration of a raspberry pi

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages