Update 07–09–2016: nix continues to evolve. So much so that a blog post like this or even the nix wiki often provides out-of-date information. I am working on an updated post about nix, but until then and after, I recommend you rely on the nix manual for authoritatve informantion about nixos and nix. If you encounter problems head straight the github repository for nix and check for related issues.
2(http://blog.timsears.com/slides/imtryingnix/imtryingnix.html)*
I have been running ubuntu 12.04 on VMWare Fusion. I started using nixos on October 6th.
That’s just 10 days ago.
So…all opinions herein are subject to change.
sudo apt-get install somepackage
rarely fails to provide what I need.“Bro, you’re running a mac. Just use brew.”
“Dude, you like the bleeding edge. Try Arch.”
As a Haskeller how could I resist this kind of marketing?
Nixos: The Purely Functional Linux Distribution
But wait there’s more!
Built on top of the Nix package manager, it is completely declarative…
Whoa.
The potential…
Boot a new machine from a .iso file, then…
$ fdisk /dev/sda # enter options n,p,1,w in sequence
$ mkfs.ext4 -j -L nixos /dev/sda1
$ mount LABEL=nixos /mnt
$ nixos-generate-config --root /mnt
$ nano /mnt/etc/nixos/configuration.nix # copy/paste a configuration.nix.
$ nixos-install
$ reboot
While it is truly possible to get a system going this way, I edited configuration about 20 times before I had it just right for my dev box. If you break something the old configuration is available from the boot menu.
Here’s my config file…
[timsears@nixos:~/blog/drafts]$ cat /etc/nixos/configuration.nix
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# Define on which hard drive you want to install Grub.
boot.loader.grub.device = "/dev/sda";
swapDevices = [ { device = "/swapfile1"; } ];
networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # I'm on a vm. Not needed.
# Select internationalisation properties.
i18n = {
consoleFont = "lat9w-16";
consoleKeyMap = "us";
defaultLocale = "en_US.UTF-8";
};
environment.systemPackages = with pkgs; [
(pkgs.texLiveAggregationFun { paths = [ pkgs.texLive pkgs.texLiveExtra pkgs.texLiveBeamer ]; })
wget
curl
emacs
xlibs.xmessage
xfce.terminal
];
nixpkgs.config.allowUnfree = true;
time.timeZone = "US/Pacific";
security.sudo.wheelNeedsPassword = false;
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
services.xserver = { displayManager.slim.autoLogin = true;
displayManager.slim.defaultUser = "timsears";
windowManager.awesome.enable = true;
windowManager.default = "awesome";
# only seem to affect login screen
virtualScreen = { x = 1920; y = 1200; };
resolutions = [{ x = 1920; y = 1200; }] ;
enable = true;
layout = "us";
};
# Define a user account. Don't forget to set a password with ‘passwd’.
users.extraUsers.guest = {
name = "timsears";
group = "users";
extraGroups = ["wheel"];
uid = 1000;
createHome = true;
home = "/home/timsears";
shell = "/run/current-system/sw/bin/bash";
};
}
There are at least three levels of configuration. Global-, user- and project- level. We already saw global level. Software packages can be enabled here…
nano /etc/nixos/configuration.nix # make changes
nixos-rebuild switch
It’s really about that simple.
You are encouraged to install software as a user with nix-env -i somepackage
See installed packages with nix-env -q
. Here’s mine so far…
cabal-install-1.16.0.2
cabal2nix-1.61
chromium-stable-with-plugins-35.0.1916.114
ghc-7.6.3-wrapper
git-1.9.4
gnome-terminal-3.10.2
haskell-hakyll-ghc7.6.3-4.5.1.0
haskell-haskell-platform-ghc7.6.3-2013.2.0.0
haskell-hoogle-ghc7.6.3-4.2.32
hasktags-0.68.7
nix-repl-1.7-1734e8a
structured-haskell-mode-1.0.2
w3m-0.5.3
xkill-1.0.4
xpdf-3.03
Eventually I will convert that to a nix expression. I expect to write a few custon expressions to install the odd missing package (like easyVision).
Here’s our first major win
You can have multiple profiles per user. (I haven’t used that feature yet.)
Or you can customize the build environment for each project.
You can put a nix expression in a project directory. Here’s a file that lives in a project I have been working on: ~/timsears/code/probmonad/default.nix
{ pkgs ? (import <nixpkgs> {})
#, haskellPackages ? pkgs.haskellPackages_ghc763
, haskellPackages ? pkgs.haskellPackages_ghc782
}:
let inherit (haskellPackages) cabal cabalInstall
distributive comonad; # Haskell dependencies here
in
haskellPackages.cabal.mkDerivation (self: {
pname = "probmonad";
version = "0.1.0.0";
src = "./.";
isLibrary = false;
isExecutable = true;
buildTools = with haskellPackages; [cabalInstall];
buildDepends = with haskellPackages; [ comonad distributive];
meta = {
license = self.stdenv.lib.licenses.gpl3;
platforms = self.ghc.meta.platforms;
};
noHaddock = true;
})
The default.nix file is mostly generated by a utility cabal2nix
.
I can comment out one line to switch ghc versions distributions. I just enter nix-shell
to drop into the chosen environment. Other projects are unaffected.
The first time you switch versions nix downloads and caches all the necessary packages. (Lazy evaluation!)
I can even hide my default environment to make sure there are no hidden dependencies in my build expression.
Dependencies can be anything. Nix will install them for you if there is a nix expression available.
[EDIT: There is a video of the talk I gave here and a Reddit discussion here]