Workstation Environments
with Nix and home-manager
dustin.lacewell@workiva.com
- Worked at Docker Inc
- Helped establish and grow DockerHub CI/CD
- Moved from San Francisco, from Chicagoland
- Obsessed with Developer UX/QoL
Workstation Environments?
- Software used for work (editors, tools, utilities, etc)
- Associated configuration
Ideal Properties
- Declarative
- Version controlled
- Reproducable
- Extensible
Nix
...a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible.
It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.
"The Purely Functional Package Manager"
Nixlang
Nix
NixOS
NixOps
Disnix
Hydra
Purity
Atomicity
Laziness
Reproducibility
HM
Nix is a package manager
- Manages packages...! 😮
- Everything is isolated under /nix
- Every package lives in /nix/store
Nixpkgs
Around 6500 packages for Linux and OSX
"On GNU/Linux, the packages in Nixpkgs are ‘pure’, meaning that they have no dependencies on packages outside of the Nix store. This means that they should work on pretty much any GNU/Linux distribution."
Bread and Butter
#> nix-channel --add https://nixos.org/channels/nixpkgs-unstable
#> nix-env -qa 'firefox.*'
#> nix-channel --update
#> nix-env -i firefox
#> nix-env -e firefox
stdenv.mkDerivation rec {
name = "hello-2.10";
src = fetchurl {
url = "https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz";
sha256 = "1im1gglfm4k10bh4mdaqzmx3lm3kivnsmxrvl6vyvmfqqzljq75l";
};
meta = {
description = "A program that produces a familiar, friendly greeting";
platforms = stdenv.lib.platforms.all;
};
}
Package Purity
Nixlang's purity -> Nix's reproducibility
/nix/store/r8vvq9kq18pz08v249h8my6r9vs7s0n3-firefox-8.0.1
/nix/store/y15i77ghwd0w0xcw8hl2cl1gs4fi9dj5-firefox-8.0.1
Text
SYMLINKS
SYMLINKS EVERYWHERE
- Dependencies are symlinks
- Profiles contain symlinks
- Profiles are symlinks
Atomic upgrades and rollback
#> nix-env --upgrade firefox #> nix-env --rollback
Nix is a language
- Functional
- (Mostly) Pure
- Lazy / Non-strict evaluation
- A "modeling" language
It has basic data types
- Integers (no floats): 5 + 5
- Strings: "hello world"
- Lists: [ "blah" name 5 ]
- Attrsets: { foo = "bar"; biz.baz = "boz"; }
Every file is an expression
# example.nix
{
foo = "bar";
biz = [ 1 "two" 3 ];
}
let expressions are nice
# let <names> in <expr>
let
filename = "config.conf";
prefix = "/etc/foo";
path = "${prefix}/${filename}"
{
file = touchFile path;
}
Functions
# { <args> }: <expr>
let
func = { prefix, filename ? "foo.conf" }: {
fullPath = "${prefix}/${filename}";
ready = false;
};
in func { prefix = "/etc/foo"; }
Files can be imported
# prefix.nix
{ filename, prefix ? "/etc/foo" }:
"${prefix}/${filename}"
# foo.nix
let
prefix = import ./prefix.nix;
in {
fooFile = prefix { filename = "foo.conf"; };
}
# {fooFile="/etc/foo/foo.conf";}
Anatomy of a Package
- Depend on other packages
- Built from some source
- Files are written to $out
- Basically a special attrset
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "hello-2.1.1";
src = fetchurl {
url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
md5 = "70c9ccf9fac07f762c24f2df2290784d";
};
buildInputs = [ tar ];
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
tar xvfz $src
cd hello-*
./configure --prefix=$out
make
make install
";
}
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "hello-2.1.1";
src = fetchurl {
url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
md5 = "70c9ccf9fac07f762c24f2df2290784d";
};
}
stdenv.mkDerivation {
name = "foo-5.4";
buildPhases = [ "buildPhase"
"installPhase" ];
buildPhase = ''
gcc foo.c -o foo
'';
installPhase = ''
mkdir -p $out/bin
cp foo $out/bin
'';
}
Packaging Harbour-CLI
- Golang CLI utility
- Uses 'Glide' for dependencies
- Produces a single binary
Use a profile?
#> nix-env --switch-profile /nix/var/nix/profiles/harbour-cli
#> nix-env -i go glide git emacs
#> emacs main.go
#> go build, etc
# default.nix
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "harbour-cli";
src = ./.;
buildInputs = [ git go glide ];
}
nix-shell
#> nix-shell
#> which go
/nix/store/2r298x93l2v48yrjp31381vcghyrnlz3-go-1.9.2/bin/go
#> emacs main.go
#> glide install && go build, etc
# default.nix
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "harbour-cli";
src = ./.;
buildInputs = [ git go glide ];
buildPhases = [ "unpackPhase" "buildPhase" ];
builderPhase = ''
glide install
go test --cover
go build -o $out/bin/harbour-cli
'';
}
Installing the package
#> nix-env -i -f .
#> which harbour-cli
/Users/dustinlacewell/.nix-profile/bin/harbour-cli
#> nix-env -i \
https://github.com/Workiva/harbour-cli/archive/master.tar.gz
NixOS
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
nix-rebuild
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Configuration.nix
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Syntax Sugar
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Repetition Blues
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Set Extension
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Functions
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Higher-order Functions
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Modularity
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Functions
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Configuration Modules
- Young, typical GNU/Linux distro
- Built on top of Nix
- Declarative system configuration
Workstation Environments with Nix
By dlacewell
Workstation Environments with Nix
Nix is the package manager of the future. Its incredibly expressive language gives us the tools to describe our workstation environments and reliably reproduce them.
- 945