Skip to content

Instantly share code, notes, and snippets.

@ashgillman
Forked from joepie91/.md
Last active February 2, 2018 00:41
Show Gist options
  • Save ashgillman/072791843997e784aa24da96c4e9878f to your computer and use it in GitHub Desktop.
Save ashgillman/072791843997e784aa24da96c4e9878f to your computer and use it in GitHub Desktop.
Nix in multi-user mode on a non-NixOS (eg. Debian) system
nix-setup-user() {
TARGET_USER="$1"
SYMLINK_PATH="/home/$TARGET_USER/.nix-profile"
PROFILE_DIR="/nix/var/nix/profiles/per-user/$TARGET_USER"
echo "Creating profile $PROFILE_DIR..."
echo "Profile symlink: $SYMLINK_PATH"
rm "$SYMLINK_PATH"
mkdir -p "$PROFILE_DIR"
chown "$TARGET_USER:$TARGET_USER" "$PROFILE_DIR"
ln -s "$PROFILE_DIR/profile" "$SYMLINK_PATH"
chown -h "$TARGET_USER:$TARGET_USER" "$SYMLINK_PATH"
echo "export NIX_REMOTE=daemon" >> "/home/$TARGET_USER/.bashrc"
echo ". /usr/local/etc/profile.d/nix.sh" >> "/home/$TARGET_USER/.bashrc"
su -lc "cd; . /usr/local/etc/profile.d/nix.sh; NIX_REMOTE=daemon nix-channel --update" "$TARGET_USER"
}

This is an installation walkthrough for the Nix package manager in multi-user mode, on a non-NixOS system. While the walkthrough focuses on Debian, instructions on different platforms should be similar.

1. Install dependencies.

For recent Debian:

apt-get install build-essential pkg-config autotools-dev dh-autoreconf libssl-dev libbz2-dev libsqlite3-dev libcurl4-openssl-dev liblzma-dev libgc-dev libdbi-perl libdbd-sqlite3-perl libwww-curl-perl libxml2 libxslt-dev libseccomp-dev

For other distributions, look for the equivalent packages.

2. Set up build users.

groupadd -r nixbld
for n in $(seq 1 10); do useradd -c "Nix build user $n" \
    -d /var/empty -g nixbld -G nixbld -M -N -r -s "$(which nologin)" \
    nixbld$n; done

3. Install Nix.

wget http://nixos.org/releases/nix/nix-1.11.16/nix-1.11.16.tar.xz
tar -xvf nix-1.11.16.tar.xz
cd nix-1.11.16/
./configure --enable-gc
make -j $(nproc)
make install

If you have more than two CPU cores, you might want to change the value of the -j flag to spare some cores.

4. Create a systemd unit file, for managing the Nix daemon.

wget -O /etc/systemd/system/nix.service https://gist.github.com/ashgillman/072791843997e784aa24da96c4e9878f/raw/c56fb796b3fcb33fe1292baa301a2b6e32e59a5c/nix.service

OR: Save this as /etc/systemd/system/nix.service:

[Unit]
Description=Nix daemon

[Service]
EnvironmentFile=-/etc/default/nix
ExecStart=/usr/local/bin/nix-daemon $EXTRA_OPTS
IgnoreSIGPIPE=false
KillMode=process

[Install]
WantedBy=multi-user.target

Create an empty /etc/default/nix:

touch /etc/default/nix

Enable and start the service:

systemctl enable nix
systemctl start nix

5. Set up user configuration

wget -O - https://gist.github.com/ashgillman/072791843997e784aa24da96c4e9878f/raw/c56fb796b3fcb33fe1292baa301a2b6e32e59a5c/.bashrc >> /root/.bashrc

OR: Source the following in your /root/.bashrc, either directly or indirectly:

nix-setup-user() {
        TARGET_USER="$1"
        SYMLINK_PATH="/home/$TARGET_USER/.nix-profile"
        PROFILE_DIR="/nix/var/nix/profiles/per-user/$TARGET_USER"

        echo "Creating profile $PROFILE_DIR..."
        echo "Profile symlink: $SYMLINK_PATH"

        rm "$SYMLINK_PATH"
        mkdir -p "$PROFILE_DIR"
        chown "$TARGET_USER:$TARGET_USER" "$PROFILE_DIR"
        
        ln -s "$PROFILE_DIR/profile" "$SYMLINK_PATH"
        chown -h "$TARGET_USER:$TARGET_USER" "$SYMLINK_PATH"
        
        echo "export NIX_REMOTE=daemon" >> "/home/$TARGET_USER/.bashrc"
        echo ". /usr/local/etc/profile.d/nix.sh" >> "/home/$TARGET_USER/.bashrc"
        
        su -lc "cd; . /usr/local/etc/profile.d/nix.sh; NIX_REMOTE=daemon nix-channel --update" "$TARGET_USER"
}

Now, whenever you create a new user - say, joepie91, you can simply do something like the following:

nix-setup-user joepie91

... and a few minutes later, joepie91 will be able to log in, and use Nix. Repeat for each user that needs access to Nix.

[Unit]
Description=Nix daemon
[Service]
EnvironmentFile=-/etc/default/nix
ExecStart=/usr/local/bin/nix-daemon $EXTRA_OPTS
IgnoreSIGPIPE=false
KillMode=process
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment