Homebrew on the lab machines

The PLSE-managed machines (whale and pipsqueak) keep their system packages minimal on purpose: patching, endpoint protection, a compiler, and a handful of basics. Nobody gets sudo for a research project, and nobody should need it. Instead, each user can run their own Homebrew in their home directory. It gives you current versions of git, python, node, rust, tmux, vim, and a few thousand other packages, and nobody else’s setup can break yours.

This page is the recipe. It takes a few minutes, and it works without sudo.

Install

Run these four commands, exactly as written:

git clone https://github.com/Homebrew/brew ~/.brew/Homebrew
mkdir -p ~/.brew/bin ~/.brew/etc/homebrew
ln -s ../Homebrew/bin/brew ~/.brew/bin/brew
echo "HOMEBREW_MAKE_JOBS=$(( ($(nproc) + 1) / 2 ))" \
  > ~/.brew/etc/homebrew/brew.env

That’s it. The first line is Homebrew itself. The symlink is the trick: brew decides where its packages live from the path it was run by, so ~/.brew/bin/brew makes ~/.brew the prefix. The last line caps how many parallel jobs a source build may use (more on that below).

Then put it on your PATH. Add this line to the end of ~/.bashrc (or ~/.zshrc if you use zsh):

eval "$(~/.brew/bin/brew shellenv)"

Log out and back in, then check:

brew --prefix      # prints /home/<you>/.brew
brew update
brew analytics off
brew install ripgrep
rg --version

The first brew command you run downloads Homebrew’s own portable Ruby, so it takes a little while. After that, most installs are “bottles”: prebuilt binaries that unpack in seconds.

Why exactly ~/.brew

Homebrew’s Linux bottles are built for /home/linuxbrew/.linuxbrew, and that path is baked into their binaries. Homebrew can relocate a bottle to a different prefix, but only one that is no longer than the original, 26 characters. /home/<you>/.brew fits for any username up to fourteen characters. Pick a longer path and every bottle that needs relocating builds from source instead, turning a ten-second install into one that takes minutes or hours.

So: do not rename it, and do not run brew through the repository path (~/.brew/Homebrew/bin/brew), which would make the repository the prefix and hit the same problem. Always ~/.brew/bin/brew, or just brew once it is on your PATH.

Be a good neighbor

These are shared machines with no scheduler and no quotas. A few packages have no bottle and must build from source, and a big build at full parallelism can eat a 128-thread box. Two things keep that in check:

What to expect

Other machines

The same recipe works on the CSE-managed research machines (recycle, bicycle, and friends), where you also cannot install system packages. Their homes live under /homes/<group>/<you>, which with a three-letter group like gws leaves room for a nine-character username inside the 26-character budget. Longer than that, and the bottles that need relocating build from source.