I am trying nixos

My setup

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.

(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.

My current setup has its pluses…

Ubuntu is very stable, never crashes. I have never felt pressure to upgrade from 12.04.

Security upgrades have never broken anything.

sudo apt-get install somepackage rarely fails to provide what I need.

rarely fails to provide what I need. Binary/libc compatible with our servers in the cloud. Easy deployment on minimially configured production box.

…and its minuses

ghc is always behind in the package manager (ubuntu 12.04 ~ ghc 7.4). I want to work on projects that require ghc 7.8.

My dev box is used for building production code.

Only my code is should break a build. Therefore I don’t want to install software that could break my code.

Setting up a dev box for a new person requires reading lots of old and potentially outdated notes to collect and install all sorts of dependencies together on a new box.

The new cabal sandboxes work, but lots of code gets recompiled and reinstalled on every project.

It’s “hard” to run multiple versions of ghc. (I might just be lazy here.)

Some suggestions I have heard

“Bro, you’re running a mac. Just use brew.”

I have tried everything on mac. Remember fink, ports?

brew is great. It makes make osx 99% like linux. Not nearly close enough.

Did you ever cross-compile with ghc?

“Dude, you like the bleeding edge. Try Arch.”

No, it just looks that way because I use Haskell.

I did run Arch for over a year. Arch is fun, has a great community and a fantastic wiki, but if you want to update one thing you need to update everything. You tend to run only the latest software and it is hard to roll back.

I broke my system more than once.

Why Nixos?

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.

Real reasons:

The potential…

for alternative environents to live safely on the same box. (nix)

to encode the configuration of a development box suitable for my company’s project. (nixos, nix).

to calculate an entire machine and deploy it to the cloud. (nixops)

Escape cabal hell forever without pinning all my dependencies.

Let’s try it out…

Install

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"; }; }

Configure (Global)

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.

Configure (User)

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).

Configure (Project)

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; })

Why this is great

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.

Impressions so far

The Good

Switching environments works well and fast after the initial setup. It’s really the first time I have been happy doing that.

The entire set of package expressions is in one git repo. That’s cool.

You literally edit one file to configure your box globally. That’s really cool.

Rolling back a bad configuration is really easy.

The Bad

You must learn how nix expressions work.

The docs aren’t great yet. You must read the code!

Nobody told me to read the manual’s Appendix B first to see all the settings available for configureing your system. There, I told you.

Sometimes blogs are more helpful than the docs.

The I Don’t Know

nixops looks powerful. I want to try it.

Some things are still arcane or rough around the edges (installing latex).

Will I be able to write an expression for Intel IPP? It’s got a weird installer.

[EDIT: There is a video of the talk I gave here and a Reddit discussion here]