Flox and Home Manager

Hi there,

I’m really seeing the value of Flox, I believe it’s a clean more consistent way to help Engineers with their day to day work.

The guide for migrating Homebrew to Flox is a step in the right direction.

I think there should be a be defined pattern on making Flox and Home Manager work better together, Flox already has a focus on making environments easier to manage but I think for Flox to get better traction there needs to be a pattern for /home management, not just for packages but for configuration as well.

The Idea: flox home

Using the workflow of installing a package it could be extended to add dotfile management
eg.
~/.flox/env/config/.vimrc/users/bob/.vimrc

When I manage install an Application and do it’s config, I can just push my config to floxhub
eg.
flox home push

When I have a new machine or environment I can just pull in my home to have it configured the way I want.
eg.
flox home pull

Not sure if this is part of a Roadmap already.

Glad to hear you’re seeing the value!

This isn’t on the near term roadmap, but I definitely think something like that could be useful

It’s 1 Year later, Googled and came across the post.
Is there anything on the roadmap for this or what patterns have emerged over the year?

Hi, thank you for the follow-up! We have not prioritized 1st class dotfile management in particular.

Although the features available to build packages and customize a flox environment may be able to be useful for your scenario.

Can you say more about how you would intend for this to work when there are existing files present at the path? For example, would you want the flox activate to overwrite or append the contents of files already in the home directory? For example, let’s say ~/.vimrc exists and has contents. What would you expect to happen if a user activated an environment with a package that contained a .vimrc ? One option is to use application-specific environment variables such as VIMINIT='source $FLOX_ENV/lib/vimrc' where the flox environment vimrc file comes from the package and does not overwrite the actual ~/.vimrc

I’m looking for a pattern similar to Mackup.


Here an Architecture diagram of it, you can either adopt a file … link(the mackup term) it.

Scenario:

An engineer clones a repo with a NeoVim config but it contains an entire LazyVim config folders, there is also have a shared a ~/.ssh/config to access machines via ansible it also has a .ansible folder with all the required roles and collections.

Related link: GitHub - lra/mackup: Backup and keep your application settings in sync.

My understanding is that mackup (or home-manager for that matter) are quite .. destructive and global in that they write to files in you user home.

I think neither quality is what we are looking for with Flox, where we try to provide lightweight virtual envs that dont cause lasting changes globally.
I think for a usecase like you describe .. sharing vim or ssh configs (disregarding the former feeling rather personal and the latter risky to share around at all) could be solved with a mix of variables in the env and optionally packages to disconnect things a bit:

I.e. you could create a package that contains the desired files:

# manifest.toml

[build.files]
description = "Ship files"
version = "0.0.1"
command = """
  mkdir -p $out/.config
  cp -r ./ssh $out/.config 
  cp -r ./vim $out/.config
  # ...
"""

publish this (in this case to <owner>/files) using flox publish

And then use this in a different environment

# manifest.toml
[install]
files = <owner>/files # renders the config files we stored earlier to $FLOX_ENV/

[hooks]
on-activate = '''
    # likely not literal, but i hope you get the idea
    export SSH_CONFIG=$FLOX_ENV/.config/ssh
    export VIM_CONFIG=$FLOX_ENV/.config/ssh
'''

As long as you keep the managing env private you can reproduce the config files anywhere you have access to the package (Note: files remain visible through /nix/store to other users on the system**)**

If you are intent to do home management, its possible to involve flox in that too by mixing in mackup as the implementor of the linking logic:

Again start with a package. this time we configure mackup to back files up into a directory that is subsequently being packaged up and can be restored from in another environment:

# manifest.toml

[build.mackup]
description = "Backup with mackup"
version = "0.0.1"
command = """
  mkdir -p $out/share/mackup
  mkdir -p $out/bin

  # create a temp config dir (in $HOME/ to make mackup happy)
  config_dir=$(mktemp --tmpdir=$HOME -d)

  # define a mackup config
  # in which we set the backup dir to something $out based

  cat << EOF > $config_dir/mackup.cfg
  [storage]
  engine = file_system
  path = $out/share/mackup
  directory = Backup

  [applications_to_sync]
  Alt-Tab
  EOF

  # Backup using Mackup
  MACKUP_CONFIG=$config_dir/mackup.cfg mackup backup --force

  # keep the config dir around (i guess you need that for restoring)
  mv $config_dir $out/share/mackup/config

  # provide a wrapper for convenience of the "other" machine
  cat << EOF > $out/bin/mackup-bundled
  #!/bin/bash
  config_dir=$(mktemp --tmpdir=$HOME -d)
  cp $out/share/mackup/config/* $config_dir
  MACKUP_CONFIG=$config_dir/mackup.cfg mackup "$@"
  EOF

  chmod +x $out/bin/mackup-bundled
"""

Other environments can then install <owner>/mackup and run mackup-bundled restore (assumably being not very familiar with mackup).


Disclaimer:

I dont necessarily recommend either in the sense that this is an official solution – more trying to help you with your usecase and show what would be possible with Flox today.

Considering that there might be a disconnect in what we think of the scope of flox vs the scope of mackup (local, lightweight, unintrusive, cooperative vs global, backup/restore, single user-ish) I’d be curious about your intended workflow (and whether that changed reading through this).

Also, when you say “Home Manager”, do you refer to GitHub - nix-community/home-manager: Manage a user environment using Nix [maintainer=@khaneliman, @rycee] or “Managing your home dir / configs in general (á la mackup)?