= Using NixOS as an stateless workstation

:empty:
:nixos: https://nixos.org/

Last
week{empty}footnote:last-week[
  "Last week" as of the start of this writing, so around the end of May 2019.
] I changed back to an
old{empty}footnote: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.
] Samsung laptop, and installed {nixos}[NixOS] 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{empty}footnote:convincend-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.
].

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:

. tap-to-click on the touchpad wasn't enabled by default;
. 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

:spacemacs: https://spacemacs.org/
:emacs: https://www.gnu.org/software/emacs/
:layers: https://spacemacs.org/doc/LAYERS.html
:there: https://nixos.org/nixos/manual/index.html#module-services-emacs-adding-packages
:packages: https://www.gnu.org/software/guix/manual/en/html_node/Application-Setup.html#Emacs-Packages

Right now I'm using the {spacemacs}[Spacemacs], which is a community package
curation and configuration on top of {emacs}[Emacs].

Spacemacs does support the notion of {layers}[layers], 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}[there is support for Emacs packages in
Nix].  So far I was only aware of {packages}[Guix support for 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

:myrepos: https://myrepos.branchable.com/

I'm using {myrepos}[myrepos] to manage all my git repositories, and the general
rule I apply is to add any repository specific configuration in myrepos'
`checkout` phase:

[source,sh]
----
# 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

:not-at-all: https://euandre.org/git/dotfiles/tree/bash/symlinks.sh?id=316939aa215181b1d22b69e94241eef757add98d
:stow: https://www.gnu.org/software/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-at-all}[not declarative at all].  I wonder if
something like {stow}[GNU Stow] can help me simplify this.

== Conclusion

:nix: https://nixos.org/nix/

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}[Nix package manager] (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._, mail me some tips].  If you don't have any experience
at all, I'd still love to hear from you.
