Remote Nix Shells

Posted on February 5, 2019 under tag(s) Nix

A minimalistic way to enter a nix-shell on a remote machine is the following: Instantiate a derivation, build it, copy its closure over and enter a nix-shell over ssh. This can be done in one operation using the following shell script:

Script

Usage: remote-nix-shell.sh <host> <nix-instantiate arguments>

#!/usr/bin/env sh
#file remote-nix-shell.sh

export NIX_SSHOPTS="source .profile" # Necessary for non-NixOS hosts.

host=$1;shift # The first argument should be the host.

echo "remote-nix-shell.sh: creating a derivation in the local store."
# the rest of the argument list is passed to nix-instantiate:
drv=$(nix-instantiate --quiet $@)

echo "remote-nix-shell.sh: building this derivation locally."
nix-store --realize $drv --quiet > /dev/null

echo "remote-nix-shell.sh: copying the derivation and its output to the host."
nix-copy-closure --include-outputs --to $host $drv

echo "remote-nix-shell.sh: entering a remote shell."
ssh -t $host "source .profile; nix-shell $drv"

Example 1

Entering the hello derivation’s environment:

./remote-nix-shell.sh user@host \<nixpkgs\> --attr hello

Example 2

Using an `env.nix` file that specifies an environment:

#file env.nix
{ pkgs ? import <nixpkgs> {}}:
with pkgs;
stdenv.mkDerivation rec {
  name = "exampleEnvironment";

  #These two lines are necessary to build a nix derivation with no source.
  installPhase = "mkdir $out";
  unpackPhase = "true";

  #The environment's content.
  buildInputs = [ hello ];
  VAR = "baz";
  shellHook = "whoami; hostname; echo $VAR; hello";

}

Usage:

./remote-nix-shell.sh foo@bar env.nix
remote-nix-shell.sh: creating a derivation in the local store.
remote-nix-shell.sh: building this derivation locally.
remote-nix-shell.sh: copying the derivation and its output to the host.
remote-nix-shell.sh: entering a remote shell.
foo
bar
baz
Hello, world!

nix-shell:~$

Back