NIX HOWTO
This HOWTO assumes you already have nix installed.
Nix Channels
We currently recommend using the Nix Unstable channel
by default as it contains the latest tested updates on a rolling basis. This
means that the branch for the NixOS/nixpkgs repository that is
used is the nixpkg-unstable branch.
Troubleshooting Git-related errors
In the step above, you may need to modify the ref="{BRANCH_NAME}"; line
with the master branch for the NixOS/nixpkgs repository if you
encounter any Git-related errors.
Trussels using Nix for package management have run into issues related to
commits not being found on that specific nixpkgs-unstable branch. The
nix-package-search will report the ref to be
nixpkgs-unstable but the actual commit may not exist on that branch due to
integration errors within the NixOS/nixpkgs repository that
eventually may correct itself.
To read up on Nix Channels, see their documentation.
While the branch nixpkgs-unstable specifically lags behind master to
thoroughly test things, some of our Truss projects are required to be
up-to-date. This means that we may need to update some ref=""; sections of
the Import statement to point to master to upgrade or downgrade a single
package in order to maintain our obligations to keep our dependencies
up-to-date.
Setting up a new project
-
Create a
nixdirectorymkdir -p
./nix -
Create
nix/update.shwith the content below and make the script executable#!/usr/bin/env bashset -euo pipefailif [ -z "${NIX_PROFILE+x}" ]; thenecho "NIX_PROFILE not set, not installing globally"echo "Try running 'direnv allow'"exit 1fi# Having NIX_SSL_CERT_FILE set means go won't use macOS keychain based certs# MOST projects can leave this alone, but if you unset it in `.envrc`# be sure to uncomment the following line# export NIX_SSL_CERT_FILE=$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crtDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"# install packagesnix-env -f "${DIR}" -i# Store a hash of this file to the hash of the nix profile# This way if the config changes, we can warn about it via direnv# See the nix config in .envrcconfig_hash=$(nix-hash "${DIR}")store_hash=$(nix-store -q --hash "${NIX_PROFILE}")echo "${config_hash}-${store_hash}" > "${DIR}/../.nix-hash" -
Create a
nix/default.nixthat looks like the below, but replace_YOUR_PROJECT_NAME_with the name of your projectletpkgs = import <nixpkgs> {};inherit (pkgs) buildEnv;in buildEnv {name = "_YOUR_PROJECT_NAME_-packages";paths = [];} -
Create/add to your
.envrcwith the following, replacing_YOUR_PROJECT_NAME_# if nix is installed, use itif [ ! -r .nix-disable ] && has nix-env; then# set NIX_PROFILE so nix-env operations don't need to manually# specify the profile pathexport NIX_PROFILE="/nix/var/nix/profiles/per-user/${LOGNAME}/_YOUR_PROJECT_NAME_"# Having NIX_SSL_CERT_FILE set means go won't use macOS keychain# based certs# MOST projects can leave this set, but if you are using go and# custom certificates, you might need to futz with this# export NIX_SSL_CERT_FILE_ORIG=$NIX_SSL_CERT_FILE# unset NIX_SSL_CERT_FILEnix_dir="nix"# add the nix files so that if they change, direnv needs to be reloadedwatch_file "${nix_dir}"/*.nixconfig_hash=$(nix-hash "${nix_dir}")store_hash=$(nix-store -q --hash "${NIX_PROFILE}")# The .nix-hash file is created by nix/update.shif [ ! -r .nix-hash ] || ! grep -q "${config_hash}-${store_hash}" .nix-hash; thenlog_status "WARNING: nix packages out of date. Run ${nix_dir}/update.sh"fi# add the NIX_PROFILE bin path so that everything we just installed# is available on the pathPATH_add ${NIX_PROFILE}/bin# If you use go, add this## nix is immutable, so we need to specify a path for local changes, e.g.# binaries can be installed local to this projectexport GOPATH=$PWD/.gopathPATH_add ./.gopath/bin# If you use node, add this#PATH_add ./node_modules/.binexport NPM_CONFIG_PREFIX=$PWD/.npmglobalPATH_add ./.npmglobal/binfi -
Use nix-package-search to find your package versions and add them to your
nix/default.nixin thepathssection. Your newdefault.nixmight look something like (with NAME replaced with your project)letpkgs = import <nixpkgs> {};inherit (pkgs) buildEnv;in buildEnv {name = "_YOUR_PROJECT_NAME_-packages";paths = [(import (builtins.fetchGit {# Descriptive name to make the store path easier to identifyname = "nodejs-14.17.0";url = "https://github.com/NixOS/nixpkgs/";ref = "refs/heads/nixpkgs-unstable";rev = "b65a64086f8c136545955d447e1918b97dad02af";}) {}).nodejs-14_x];} -
Use
direnv allowto set up the new environment variables -
Run
./nix/update.shto install the packages. It might take a while the first time and there isn't a progress bar or anything to let you know it's working -
When the update script finishes, you are ready to go
-
You can then update
nix/default.nixwhen you need to add/update packages and thendirenvwill let you know your packages are out of date and you need to run./nix/update.sh