Easy devops with nix and Yesod
I did a website with Nix, and Yesod, a framework in Haskell.
I actually ran into multiples issues :
- I need to build the test server
- I need to build a docker for the final deployment (the target is on kubernetes)
- I need install it my Nixos server to test easily on mobile.
Sadly, by using the default toolchain, (Stack and a DockerFile), I would need to maintain a way to build my server in multiple ways. So I decided to just use nix instead.
Where Nix really doesn’t shine is in its documentation (yet!). I did need a lot of research to actually setup the tools properly : Stack needs to have ghc installed with all the proper dependencies to work, and it is needed by the development server provided by the Yesod framework.
Simply creating a shell with pkgs.haskellPackages.callCabal2nix ./. {} does not work, since it doesn’t provide GHC with the packages in a way that Stack can see, which will force it to re-download the whole toolchain. So I needed actually use
pkgs.haskellPackages.ghcWithPackages
(pkgs: myPkg.getCabalDeps.libraryHaskellDepends);
in my shell to actually be able to use yesod devel.
Generally, to make a docker, we try to build inside a first docker, and then copy everything to a smaller image, generally alpine, and try to uninstall everything that isn’t needed. This is in fact often harder than just finding all dependencies to build with nix, and then create a distroless image with nix. Only problem is that I got an image around 40mb bigger since I didn’t use musl, and nix’s glibc is pretty big. I could easily by replacing pkgs with pkgs.musl in my flake compile it for musl, but it takes a few hours to recompile every dependency, and I deem it not worth the trouble as I will only deploy one instance. (If we had a cachix instance and wanted to deploy multiple instances, theses drawbacks would become meaningless.)