[Nix](https://nixos.org) is an incredible project and has completely change the way I think about configuring linux and macOS environments. Recently, I moved my personal server from Ubuntu to NixOS to match my desktop environment. ([dotfiles here!](https://github.com/zackartz/nixos-dots)). In doing so, I realized I needed to move this blog over, too. I could simply deploy a docker container like I did before, but I think it would be interesting and informative to try and build a NixOS module around it. Hopefully you find it useful :)
## The `flake.nix` file.
Nix has a experimental feature called [flakes](https://nixos.wiki/wiki/Flakes), if you've been in the NixOS space long enough you've undoubtably heard of them. Flakes are a new way of writing your package configuration, you expose two objects, `inputs` and `outputs`. Your `inputs` would be things your application depends on, for example, `nixpkgs` (the package repository of Nix). Inputs can be a variety of different things, but typically are git repos. A `flake.lock` file is generated automatically so any consumers of your flake get the exact revisions of each input to guarantee reproducability. The `outputs` section of your flake can contain many things, from `devShells` to entire `nixosConfigurations`, but we are interested in `packages` and `nixosModules` today.
A example for a starter flake for a Astro project may look like this:
You can see for my inputs I am taking in `nixpkgs` and `nix-systems`, which I am using to generate a devShell for every system architechture supported by NixOS. The `devShells` all import the following nix packages, `nodejs`, `pnpm`, `typescript`, `typescript-language-server`, `tailwindcss-language-server`, `astrojs-lanaguage-server`. Lets add add a package!
I use [pnpm](https://pnpm.io) as my package manager of choice, and as such we have to add the `pnpm2nix` flake to our inputs, which we can do with the following line.
about index.html blog-placeholder-3.jpg blog-placeholder-about.jpg sitemap-0.xml
blog blog-placeholder-1.jpg blog-placeholder-4.jpg favicon.svg sitemap-index.xml
```
At this point, we could add this repo as a input to the flake configuring our server, add a new `virtualHost` for the domain we want this to run on, point the root at this package and call it a day, but I want to take it one step further. I want to write a NixOS module to make the configuration server side even easier.
Because Nix (the language) is mostly used for configuration, defining variables anywhere could be confusing, so you have to do it in a special scope, that being the `let .. in` syntax. In this example, we are setting the variable `cfg` to be equal to `config.zmio.blog`, for convenience. Notice also the `with lib;`, this allows us to call the values on `lib` as a top-level var, ie, `lib.mkOption` would become `mkOption`.
The `options.zmio.blog` object contains the options, their types and their defaults, and the `config` section is the code that gets executed.
Enough code, lets deploy!
## Deploying on the server
After adding the repo of my blog project to my server's flake like this:
We can add the following to our server's main nixosModule:
```nix
zmio.blog.enable = true;
```
And that should be it, after a rebuild it should be live!
## Conclusion
NixOS allows for a truly unique way of deploying apps, and if you thought this was interesting, be sure to check out Nix! There's tons of other cool stuff to check out!