Jekyll Development Environment on Nix

An isolated and reproducible Ruby development environment for my website.

While playing with Nix, I found the ‘nix-shell’ command. I think of it as a lightweight container. Specify the dependencies, and Nix builds a sandboxed ephemeral environment. Exit the shell and everything is gone. It's a great way to keep my projects clean and reproducible: one project’s tools can’t pollute another.

I needed a small project to get my hands dirty. This website is an easy one to start with. It’s built with Jekyll, so it needs Ruby, two gems and ImageMagick (to convert some images).

Nix built-in Bundler environment makes this easy. Start with a ‘default.nix’ file in the root of the project.

with (import <nixpkgs> {});
let env = bundlerEnv {
  name = "suffix";
  ruby = ruby;
  gemfile = ./Gemfile;
  lockfile = ./Gemfile.lock;
  gemset = ./gemset.nix;
default.nix (part 1)

This should be self-explanatory, except for the ‘gemset.nix’ part. This file is a ‘Gemfile.lock’ but with checksums for each gem as Nix requires. To create it, use the Bundix tool:

nix-shell -p bundix --run bundix

Next, add the dependencies and optionally a ‘shellHook’ to start the Jekyll server. I added ImageMagick as an example for other dependencies that might be needed.

in stdenv.mkDerivation {
  name = "suffix"
  buildInputs = [bundler ruby imagemagick];
  shellHook = ''
    exec ${env}/bin/jekyll serve
default.nix (part 2)

Tadaa! A full reproducible auto cleaning Jekyll development environment on any Nix system from a single command: simply run ‘nix-shell’ from the root.

A project can have multiple .nix configs: a ‘tests.nix’ for example with different databases or Ruby versions.

More Resources