= Using NixOS as an stateless workstation

date: 2019-06-02

layout: post

lang: en

ref: using-nixos-as-an-stateless-workstation

---

Last week[^last-week] I changed back to an old[^old-computer] Samsung laptop, and installed
[NixOS](https://nixos.org/) on it.

After using NixOS on another laptop for around two years, I wanted
verify how reproducible was my desktop environment, and how far does
NixOS actually can go on recreating my whole OS from my configuration
files and personal data. I gravitated towards NixOS after trying (and
failing) to create an `install.sh` script that would imperatively
install and configure my whole OS using apt-get. When I found a
GNU/Linux distribution that was built on top of the idea of
declaratively specifying the whole OS I was automatically convinced[^convinced-by-declarative-aspect].

I was impressed. Even though I've been experiencing the benefits of Nix
isolation daily, I always felt skeptical that something would be
missing, because the devil is always on the details. But the result was
much better than expected!

There were only 2 missing configurations:

1.  tap-to-click on the touchpad wasn't enabled by default;
2.  the default theme from the gnome-terminal is "Black on white"
    instead of "White on black".

That's all.

I haven't checked if I can configure those in NixOS GNOME module, but I
guess both are scriptable and could be set in a fictional `setup.sh`
run.

This makes me really happy, actually. More happy than I anticipated.

Having such a powerful declarative OS makes me feel like my data is the
really important stuff (as it should be), and I can interact with it on
any workstation. All I need is an internet connection and a few hours to
download everything. It feels like my physical workstation and the
installed OS are serving me and my data, instead of me feeling as
hostage to the specific OS configuration at the moment. Having a few
backup copies of everything important extends such peacefulness.

After this positive experience with recreating my OS from simple Nix
expressions, I started to wonder how far I could go with this, and
started considering other areas of improvements:

== First run on a fresh NixOS installation

Right now the initial setup relies on non-declarative manual tasks, like
decrypting some credentials, or manually downloading **this** git
repository with specific configurations before **that** one.

I wonder what some areas of improvements are on this topic, and if
investing on it is worth it (both time-wise and happiness-wise).

== Emacs

Right now I'm using the [Spacemacs](http://spacemacs.org/), which is a
community package curation and configuration on top of
[Emacs](https://www.gnu.org/software/emacs/).

Spacemacs does support the notion of
[layers](http://spacemacs.org/doc/LAYERS.html), which you can
declaratively specify and let Spacemacs do the rest.

However this solution isn't nearly as robust as Nix: being purely
functional, Nix does describe everything required to build a derivation,
and knows how to do so. Spacemacs it closer to more traditional package
managers: even though the layers list is declarative, the installation
is still very much imperative. I've had trouble with Spacemacs not
behaving the same on different computers, both with identical
configurations, only brought to convergence back again after a
`git clean -fdx` inside `~/.emacs.d/`.

The ideal solution would be managing Emacs packages with Nix itself.
After a quick search I did found that [there is support for Emacs
packages in
Nix](https://nixos.org/nixos/manual/index.html#module-services-emacs-adding-packages).
So far I was only aware of [Guix support for Emacs packages](https://www.gnu.org/software/guix/manual/en/html_node/Application-Setup.html#Emacs-Packages).

This isn't a trivial change because Spacemacs does include extra
curation and configuration on top of Emacs packages. I'm not sure the
best way to improve this right now.

### myrepos

I'm using [myrepos](https://myrepos.branchable.com/) to manage all my
git repositories, and the general rule I apply is to add any repository
specific configuration in myrepos' `checkout` phase:

```shell
# sample ~/.mrconfig file snippet
[dev/guix/guix]
checkout =
  git clone https://git.savannah.gnu.org/git/guix.git guix
  cd guix/
  git config sendemail.to guix-patches@gnu.org
```

This way when I clone this repo again the email sending is already
pre-configured.

This works well enough, but the solution is too imperative, and my
`checkout` phases tend to become brittle over time if not enough care is
taken.

### GNU Stow

For my home profile and personal configuration I already have a few
dozens of symlinks that I manage manually. This has worked so far, but
the solution is sometimes fragile and [not declarative at all][symlinks]. I
wonder if something like [GNU Stow][stow] can help me simplify this.

[symlinks]: https://euandre.org/git/dotfiles/tree/bash/symlinks.sh?id=316939aa215181b1d22b69e94241eef757add98d
[stow]: https://www.gnu.org/software/stow/

## Conclusion

I'm really satisfied with NixOS, and I intend to keep using it. If what
I've said interests you, maybe try tinkering with the [Nix package
manager](https://nixos.org/nix/) (not the whole NixOS) on your current
distribution (it can live alongside any other package manager).

If you have experience with declarative Emacs package managements, GNU
Stow or any similar tool, *etc.*,
[I'd like some tips](mailto:{{ site.author.email }}). If you don't have any
experience at all, I'd still love to hear from you.

[^last-week]: "Last week" as of the start of this writing, so around the end of
    May 2019.

[^old-computer]: I was using a 32GB RAM, i7 and 250GB SSD Samsung laptop. The
    switch was back to a 8GB RAM, i5 and 500GB HDD Dell laptop. The biggest
    difference I noticed was on faster memory, both RAM availability and the
    disk speed, but I had 250GB less local storage space.

[^convinced-by-declarative-aspect]: The declarative configuration aspect is
    something that I now completely take for granted, and wouldn't consider
    using something which isn't declarative. A good metric to show this is me
    realising that I can't pinpoint the moment when I decided to switch to
    NixOS. It's like I had a distant past when this wasn't true.
