Building a web app with functional programming - NixOS

Summary

This is the last article of this series and will focus on my experience with NixOS.

In a nutshell, NixOS is a operating system based on Linux that provides a declarative package and configuration management.

Please note this article was written upon my experience that started months ago. I know there have been great improvements since and people are making NixOS better everyday. So this post may not be relevant anymore in a near future.

Introduction

Let me begin by writing why I chose NixOS. When I started PatchGirl, I originally thought I would have my hands full with learning Elm and improving my Haskell knowledge. I hence went with a more traditional Docker approach.

My concern at the time was to be able finish my project and learning yet another language felt too much. But because it went smoothly with both Haskell and Elm, I thought I’d learn something else. So I ditched Docker and dived into NixOS.

I have spent countless hours debugging Docker files, learning, installing and configuring Linux services and never have I liked it.

I love to code softwares but I’m not a big fan of doing system administration and devops work mainly because I find it hard. Still, I often need to get my hands dirty by setting up some services so I might as well learn something new (and hopefully better) in the process.

Currently, NixOS is quite trendy in the world of functional programming and was on my bucket list for a while, so it was the perfect candidate for PatchGirl.

Installation

NixOS is an operating system so you can’t install it like Docker with a simple brew install or apt-get install . You actually need to setup the OS of your computer. I haven’t tried the graphical installation though I assume it is beginner friendly. On the other hand, the non graphical installation will require a bit of knowledge on partitioning/formatting hard drive.



Installing NixOS is quite longer and harder than Docker but for me, it was seamless and I was delighted to see that the official NixOS manual was really helpful in the process.

Reproducible build

Everytime I heard about NixOS, people would pinpoint how great it is for reproducible build/system. Nonetheless, when you start reading the official guide, you’ll find no trace of reproducible system. There is a great deal about Channels that is in a nutshell, a way to install packages from a list of curated packages but channels are not meant for reproducible build.

Instead, what you need is to pin your package to a specific version. You’ll find how to do this by looking for NixOS pinning in google or simply by going to this page.

Once you have that, installing a specific version of a package is a piece of cake.

I thought it was a pity that this (really important and useful feature in my opinion) was not in the default manual next to the channel section.

Installing and configuring a system/package/service

One of the NixOS main benefit is its declarative configuration file. You use it for literally everything, installing package, services, configuring your system and how everything works together…

I honestly love it. It feels so nice to have all your configuration at the same place with the same format. Installing a package is a piece of cake and configuring a service sometimes feel dead simple. See for example how to configure nginx to use and configure ssl automatically:

services . nginx = { enable = true ; virtualHosts . "yourhost.com" = { forceSSL = true ; enableACME = true ; root = " ${ home } /application/public" ; locations . "/api" . proxyPass = "http://127.0.0.1:3000" ; }; };

Et voila! You only need to run nixos-rebuild switch and within seconds your system is updated to use nginx with ssl.

Same for the system:

users . users . john = { isNormalUser = true ; group = "john" ; extraGroups = [ "wheel" ]; # Enable ‘sudo’ for john. };

You now have a john user on your OS. Easy peasy!!

It’s hard to describe with plain words how amazing configuration management is with NixOS and it’s even simpler with bare packages.

Sometimes though, you’ll find configuring a service through NixOS configuration too hard. You might want your service to behave in a really specific way, or your already existing configuration is cumbersome to translate to Nix language then you shouldn’t worry as NixOS let you use regular configuration as well. I personnaly haven’t had the need yet but I’m relieved to know it exists.

Documentation

This is NixOS biggest drawback in my opinion. I truly love NixOS but gosh it was hard to learn. When it comes to learning and understanding it, the official documentation is good but far from exhaustive and aside from it, learning materials are scattered everywhere on the internet.

From some github’s repos to individual blog posts, the documentation is hard to gather for the beginner.

Conclusion

Not yet tested

There are still some promising features that I haven’t tried yet. Currently, I only have PatchGirl deployed as a git repo on my NixOS server. So everytime I want to deploy a new version I have to ssh and then git pull …

NixPkgs allows you to wrap your package with a declarative configuration and make your project buildable from any platform that would have access to NixPkgs. Moreover you can deploy a package by using NixOps.

NixOps and NixPkgs are definitely on my bucket list of the project I need/want to try. I’ll definitely write a blog post when I have!

Production ready?

Well, it pains me to say it but I do not consider NixOS to be production ready yet. It clearly is an amazing piece of work and I would never go back on a more traditional OS.

Learning materials are unfortunately way too sparsed. NixOS feels like a whole new world you need to explore by yourself until you’ve figured it out (but if you have the time, it’s worth it!).

Last word?

NixOS is an amazing project with more than 2000 collaborators. It will completely change the way you think about managing softwares for the better. Over the past few months, I have come to appreciate it to the point that I do not consider to use anything for my current and future projects.

It is one of the most underrated software I have came across and the industry would beneficiates a lot by using it.

As of today, the learning curve feels a bit too tight to be massively adopted, but I’m hopeful it will improve!

This is the end of building a web app with functional programming series. I hoped it convinced some readers to give either Elm, Haskell or NixOs a try as they are all unique and will bring you a new way of designing softwares.

As for me, I’ll keep exploring them in personal projects!