Home-Manager: Am I missing something?

TLDR; After my first attempt at using Home-Manager I have three questions.

  • Am I missing something? After trying H-M out I was left a little underwhelmed, but it seems like it is almost universally paired with flakes, in blogs, guide, ect.
  • I created a bash script that was inspired by GNU Stow, that copies a file from a target location, and overwrites or creates the file in a new location. Are there any dangers / problems with managing dotfiles this way, and is there a NixOS module that does something similar.
  • If there is not already a module that preforms this function, would this be a reasonably possible for someone to create as a beginner programming project?

I recently tried out Nix Home-Manager, and while I can deffinately see the usefullness for other situations. As someone using NixOS on a single user machine, it seems a bit underwhelming. Mostly just moving my installed packages from one list to another. The configuration wrapper seems like an awesome concept. But even for something like Git, I wasn’t able to translate all my settings, and ultimately it left me feeling like it was adding way more complexity than use. However in almost any guide, blog, ect, that talks about Nix, and especially about advanced stuff like flakes. It talks about pair it with Home-Manger. So am I missing / misunderstanding something?

In order to try and find my own solution to dotfile management. I created a bash script to deploy configuration files from a central storage repository. Inspired by GNU Stow, only it preforms the copy and overwrite as part of the nixos-rebuild actions.

#!/bin/bash

# Template : mkdir -p targetDirectory && cp -f originFile targetLocation

# NixOS
echo "Deploying configuration.nix"
mkdir -p /etc/nixos && cp -f /home/que/Projects/Technonomicon/NixOS/configuration.nix /etc/nixos/configuration.nix
echo "Deploying nix-stow.sh"
mkdir -p /etc/nixos/system-scripts && cp -f /home/que/Projects/Technonomicon/NixOS/System-Scripts/nix-stow.sh /etc/nixos/system-scripts/nix-stow.sh

# Emacs
echo "Deploying init.el"
mkdir -p /home/que/.config/emacs && cp -f /home/que/Projects/Technonomicon/Emacs/init.el /home/que/.config/emacs/init.el

echo "Rebuilding NixOS"
nixos-rebuild switch

Are there any major issues I am likely to run into doing things this way?

Lastly. Is there a NixOS module that does someting similar to this as part of the configuration.nix. I understand that Home-Manager supports importing config files, but if I don’t want it to do any other package management operations. Then that seems like overkill. If not… would this be a reasonable thing for a beginner to try and create. I have started poking at a couple guides on writing nix pkgs, but I have no idea how to judge how complex this would actually be to implement, beyond that I can do it with bash. Thanks.

What is it you’re actually looking for? If you care about exactly… 1 configuration file, configuration.nix which you really shouldn’t be copying around, just use a flake/-I nixos-config=, and nix-stow.sh, which I guess is this script and becomes useless once you have your configuration in place… Well, maybe this is overkill.

If on the other hand, you have more configuration than just emacs, well the issue with your script is that it only captures a small part of your configuration, and you may well end up having to reinvent a whole bunch of it next time you get a new computer.

The other problem is file permissions, you’re mixing files that should be owned by root/your user without explicit permissions, which is a recipe for permission problems. And you assume they all exist in the same directory on all systems, so you’ll need to rewrite the script if you ever clone to a different place.

The benefit to me from home-manager should be obvious from a glance at my repository: GitHub - TLATER/dotfiles: Dotfiles deployed with nix/home-manager. Feel free to take what you like!

It’s horrendously complicated! Managing the systemd units alone was a pain before I started using home-manager, and that’s not even getting started on how inconsistently my shell configuration worked. I also have a bunch of downstream packages, and depend on 3rd party configuration snippets that I sometimes want to update (bits of oh-my-zsh, firefox extensions, firefox UI settings, stumpwm “contrib” stuff, …). Oh, and because I’m a snowflake I need different configurations for different computers (especially work/personal, and VM/physical).

Using home manager gives me the flexibility to maintain this without going insane, and actually permits having multiple slightly different configurations without them drifting apart. It’s all in git. It’s awesome, and the main reason I started using NixOS!

I was skeptical about using nix as a package manager at first, rather than just a configuration manager, too, since I still wanted to be able to use my config on non-NixOS machines with distro-native packages. Some of that hesitancy still shows in the clunkier bits of my config. But having it turned out to be so useful - I’m tracking every single package that I need for my day-to-day usage. All the complicated tooling setup you need to get emacs to do language servers, emails, you name it? Everything installed by nix, updated by nix, and if my computer goes up in flames it takes me maybe 10 minutes to get back to exactly where I was. It also still works on other distros, and I don’t have to deal with ancient emacs versions on debian anymore.

And hey, home-manager even comes with built-in, pre-written modules for a lot of the software I use. I was hesitant to use these at first too, but I really should use them more… Small subtle problems in your personal configuration being worked on by a team of extremely skilled software integrators with personal interest in it is actually nice. Even if it means that you need to commit to the nix ecosystem.

What were your specific issues? You can translate every single git setting to home-manager settings, here are mine: dotfiles/default.nix at c0e84ba376943f57e9708241d1dbf51d23f53a33 · TLATER/dotfiles · GitHub

Also maybe you missed the options manual? Appendix A. Configuration Options

Nix can be a bit tricky to learn up-front. People here are generally helpful and patient, show us your problems and someone will explain how you get where you want to be.

Lastly. Is there a NixOS module that does someting similar to this as part of the configuration.nix . I understand that Home-Manager supports importing config files, but if I don’t want it to do any other package management operations. Then that seems like overkill.

In theory you can do that, but the most user-friendly module for doing that is integrated into home-manager. The reason is that it’s a little bit annoying to write a module just for a specific user with NixOS modules, because it’s really designed to deploy the full os.

I think if home-manager were simply part of NixOS (which is always suggested when someone comes along with “but I don’t want to use home-manager, I want to use NixOS!”), you likely would never consider it overkill because you wouldn’t notice, and ignore the rest. There is almost no additional cost, just a few MB of drive space you don’t use.

So my suggestion is, try using home-manager’s config file module. If you still desperately want something “simpler”, you can then always copy those modules out into your own project and call it home-manager-- or something.

1 Like

One of the neat things about Nix is it really lowers the barrier for using some tool.

A tool doesn’t need to be mind-blowingly excellent to be worth using. It needs to be nicer in enough cases. – e.g., I could probably live with find and grep instead of using fd and rg. But, the latter ease over enough rough edges that I always install them.

TBH, this bash script is a very naive approach to managing dotfiles, especially compared to using something like dotbot.

e.g. you’ve hardcoded the full path of where the init.el file is copied from, which constrains you to only be able to use your configuration files if you’ve got your git repository in exactly that location. – Most of the benefit from putting in effort to have a dotfiles repository is being able to share config files across computers. (e.g. servers you SSH into, or whatever).

e.g. your script involves manually adding an echo statement before each line; and manually adding mkdir -p. – That’s at least boilerplate you’ll need to copy for each config file you want to manage.

One danger from code where you’re going to just copy-paste snippets is you’ll forget to properly edit bits, and it will be difficult to notice.

I know it’s tangential to you point, but I want to point out: compare the installation steps for non-flake standalone vs the setup for flakes standalone.

For non-flakes, it requires nix-channel --add & nix-channel --update, plus some other invocation.

The flakes based setup requires adjusting a flake.nix, and has a couple of arcane setup commands to run.

Considering that you’ll most likely be putting your configuration files in Git, I see it as ultimately more convenient to not have to run nix-channel --add to make use of the configuration.

home manager does this itself, there is no need to reinvent this part. Anything under your home.files will be handled analougous to environment.etc on NixOS. Plenty of the modules use this under the hood to place config files, etc.

Are there any dangers / problems with managing dotfiles this way

You have to run that script as root to mkdir/cp files in /etc/nixos right? So then your emacs config directory is owned by root rather than you. This is going to cause problems with emacs creating files like eln-cache, history, recentf and other caches/local data unless you have your emacs configured to create that stuff elsewhere. This also means potentially overwriting local data that got saved there (if it can be) every time you run your script which means losing data. I also don’t know if emacs will have issue running any files with root permissions.

Secondly, you now have two copies of your emacs configs. For me, this is always going to end badly since I’m frequently making minor tweaks. You’ll either have to modify your git controlled version then remember to rerun the script every time you need to make a change or directly modify the copy (which is owned by root) and not have the changes in your git repo. This is why stow uses symbolic links rather than actually copying the files. You can modify them in either place without having to worry about syncing them up.

Even if you don’t want to use home-manager why not use stow? It won’t be able to link /etc/nixos/configuration.nix for you but I belive you can link /etc/nixos/configuration.nix to the copy in your git repo manually one time as root and the file will remain owned by you so you can make changes then run rebuild whenever needed. This also prevents unnecessary rebuilds if you’ve only changed your emacs configuration.

Thank you everyone. I added individual responses below, this is a more general background section. The goal of this script in general was to create a “single source of truth” for my configuration. Right now building my configuration sort of is my project, and I have been having issues with losing changes while needing to manually copy files around. The hope was that this would eliminate that, imitate the normal behavior of nix. While making the set up process as scripted as possible. Since I still occasionally revert to my primary problem solving tool from Debian, reinstalling the OS.

I think part of the issue is that I am trying to create temporary solutions to solve problems, while not being sure what my final configuration will actually entail. I have a few concepts floating around but they still seem a long way off. With a lot to learn in between, without getting caught in the circle of learning this to be able to learn that.

Sorry, I should have been more explicit about that. The script I posted is just a section of a larger file to show how the script generally operates. I was unaware of the issue with file permissions, thank you for explaining that. I also hadn’t considered shell configs interacting with nix-shells.

As to git I had looked through the appendix, but couldn’t find any options regarding setting rebase to false. Thank you for sharing you config, I am probably going to spend a good while digging through it.

I have been incredibly impressed by this forum, and the level of support available on here. I am also joining the Nix matrix to try and engage there for smaller more limited conversations.

For what it’s worth, I totally agree with this. If the Nix user and home-manager user sections were just the same, then there would be no increase in perceived effort/complexity on the user end.

I see what you are saying, and as @DavidRConnell mentioned simply using stow + a hard link for configuration.nix would be a better way to go.

I think short term I probably will. Right now I am just trying to find a way to not lose config changes again, while I am making large changes to the system configuration basically daily, and this way seemed to make these system changes a part of the nix system rebuild.

Thank you again everyone!