Home Manager: Difference between revisions

From NixOS Wiki
imported>Luis-Hebendanz
mNo edit summary
H7x4 (talk | contribs)
Add link for a keyword
 
(48 intermediate revisions by 37 users not shown)
Line 1: Line 1:
[https://github.com/rycee/home-manager Home Manager] is a basic system for managing a user environment using the Nix package manager together with the Nix libraries found in Nixpkgs. Before attempting to use Home Manager [https://github.com/rycee/home-manager#words-of-warning please read the warning].
[https://github.com/nix-community/home-manager Home Manager] is a system for managing a user environment using the Nix package manager. In other words, Home Manager lets you
* install software declaratively in your user profile, rather than using nix-env
* manage dotfiles in the home directory of your user.
Home Manager has many [https://nix-community.github.io/home-manager/options.xhtml options], which can look daunting at first, but most of those options only boil down to creating some dotfiles and installing some software in a way similar way to nix-env.
 
{{Note|Before attempting to use Home Manager [https://github.com/rycee/home-manager#words-of-warning please read the warning].}}


== Configuration ==
== Configuration ==


Home Manager can be configured in <code>~/.config/nixpkgs/home.nix</code> or inside configuration.nix.
Home Manager can be configured as a user in <code>~/.config/home-manager/home.nix</code> or as a module inside configuration.nix.
 
=== Installation as a user ===
 
Follow the [https://nix-community.github.io/home-manager/index.xhtml#ch-installation official guide]
 
Your configuration is stored in <code>~/.config/home-manager/home.nix</code>. Each time you modify it, rerun <code>home-manager switch</code> for changes to have effect.
 
Note that to work correctly, home-manager needs your shell to source <code>~/.nix-profile/etc/profile.d/hm-session-vars.sh</code>. The most convenient way to do so is to have home-manager manage your whole shell configuration, eg <code>programs.bash.enable = true;</code> or <code>programs.zsh.enable = true;</code>. But in this case your whole bashrc is managed with Home Manager: the years of customization you accumulated in your former .bashrc must be migrated to Home Manager options, which may take some time. The quick and dirty way to do the migration is to move your bashrc to some other location and source it from Home Manager:
<syntaxhighlight lang="nix">
{ pkgs, ...}: {
  programs.bash = {
    enable = true;
    bashrcExtra = ''
      . ~/oldbashrc
    '';
  };
}
</syntaxhighlight>
 
=== Usage as a NixOS module ===


For the latter, add the following to your config. Note: fetchTarball does not check the integrity of the downloaded Package.
Here is a nixos module template you can use:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ config, pkgs, ... }:
let
  home-manager = builtins.fetchTarball "https://github.com/nix-community/home-manager/archive/master.tar.gz";
in
{
   imports = [
   imports = [
     ...
     (import "${home-manager}/nixos")
    "${builtins.fetchTarball https://github.com/rycee/home-manager/archive/master.tar.gz}/nixos"
   ];
   ];
   home-manager.users.my_username = { ... }
 
   home-manager.users.my_username = {
    /* The home.stateVersion option does not have a default and must be set */
    home.stateVersion = "18.09";
    /* Here goes the rest of your home-manager config, e.g. home.packages = [ pkgs.foo ]; */
  };
}
</syntaxhighlight>
</syntaxhighlight>
It can either be incorporated in <code>/etc/nixos/configuration.nix</code> or be placed in a standalone file and imported in configuration.nix: <code>imports = [ ./thefile.nix ]</code>.
Whenever you change you home-manager configuration, you must rerun <code>nixos-rebuild switch</code>. With this method, changing the configuration of an unprivileged user requires to run a command as root.


For a more secure version:
=== Usage as a NixOS module in a Flake ===
Here is the skeleton of how to add Home Manager as a module to your system(s) via your [[Flakes|flake]]:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
let
{
   home-manager = builtins.fetchGit {
   inputs = {
     url = "https://github.com/rycee/home-manager.git";
     nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
    rev = "dd94a849df69fe62fe2cb23a74c2b9330f1189ed"; # CHANGEME
    home-manager = {
     ref = "release-18.09";
      url = "github:nix-community/home-manager/release-24.05";
      inputs.nixpkgs.follows = "nixpkgs"
    };
  };
  outputs = { self, nixpkgs, home-manager, ... }@inputs:
     nixosConfigurations.ExampleMachine = nixosConfiguration "ExmapleMachine"
      system = "x86_64-linux";
      modules = [
          ./configuration.nix
          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.your-username = import ./home.nix;
        };
      ];
    };
   };
   };
in
}
</syntaxhighlight>
     
Here's an example of home manager configuration in ./home.nix
<syntaxhighlight lang="nix">
{ config, pkgs, ... }:
 
{
{
    imports = [
  # Home Manager needs a bit of information about you and the
      "${home-manager}/nixos"
  # paths it should manage.
  ];
  home.username = "your-username";
  home.homeDirectory = "/home/your-username";
 
  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "24.05";


    home-manager.users.my_username = { ... }
  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}
}
</syntaxhighlight>


    
Of course you'll probably want to keep more stuff in there than just a state version, but the state version is required.
 
The downside to doing it this way over the User config is that you have to do a full system rebuild; the home manager config is part of the full system, and so must be built as root or at least a trusted user.
 
== Usage ==
 
=== Using Home Manager as a declarative version of nix-env ===
 
Nix-env has problematic behavior due to its imperative nature. For example, after installing java 8 with
<code>nix-env -i jdk8</code>, running <code>nix-env --upgrade</code> upgrades java to 10 despite the fact that we initially explicitly requested java 8.
 
Installing software with Home-manager avoids this problem:
<syntaxhighlight lang="nix">
{ pkgs, ...}: {
   home.packages = [ pkgs.jdk8 ];
}
</syntaxhighlight>
</syntaxhighlight>


== Managing your dotfiles ==
It is a perfectly valid use case for home-manager to only install software with <code>home.packages</code> without managing dotfiles at all.
 
=== Usage on non-NixOS Linux ===
 
Home Manager has an option to automatically set some environment variables that will ease usage of software installed with nix on non-NixOS linux (fixing local issues, settings XDG_DATA_DIRS, etc.):
<syntaxhighlight lang="nix">
{ pkgs, ...}: {
  targets.genericLinux.enable = true;
}
</syntaxhighlight>
 
=== Managing your dotfiles ===


Home Manager has options to configure many common tools. As an example, adding the following
Home Manager has options to configure many common tools. As an example, adding the following
Line 46: Line 146:
will make Home Manager generate a <code>.config/git/config</code> file for you.
will make Home Manager generate a <code>.config/git/config</code> file for you.


Even for programs for which Home Manager doesn't have configuration options, you can use it to manage your dotfiles, e.g.
Even for programs for which Home Manager doesn't have configuration options, you can use it to manage your dotfiles directly, e.g.
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
   home.file.".config/i3blocks/config".source = "${my-dotfile-dir}/i3blocks.conf"
   xdg.configFile."i3blocks/config".source = ./i3blocks.conf;
  home.file.".gdbinit".text = ''
      set auto-load safe-path /nix/store
  '';
</syntaxhighlight>
</syntaxhighlight>


This will create a symlink <code>.config/i3blocks/config</code>.
This will create symlink <code>$XDG_CONFIG_HOME/i3blocks/config</code> and <code>~/.gdbinit</code>.
 
{{Note|In both ways ("source" and "text"), the symlink points to a target in /nix/store. The difference is that, "source" would overwrite the content of the dot file, while "text" would add the text to the dot file that may also be affected in other places.}}
 
You have the whole list of the options available in home-manager [https://nix-community.github.io/home-manager/options.xhtml here]


=== Examples ===
=== Examples ===
* [https://github.com/yrashk/nix-home/blob/master/home.nix Yurii Rashkovskii's home.nix]
* [https://github.com/yrashk/nix-home/blob/master/home.nix Yurii Rashkovskii's home.nix]
* [https://git.sr.ht/~ben/config bsima's configs]
* [https://git.sr.ht/~ben/config bsima's configs]
* [https://github.com/drupol/nixos-x260 drupol's config, with flakes]
== FAQ ==
=== I cannot set GNOME or Gtk themes via home-manager ===
If you get [https://nix-community.github.io/home-manager/index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal an error about {{ic|ca.desrt.conf}} or {{ic|dconf.service}}] on NixOS, add
<syntaxHighlight lang=nix>
programs.dconf.enable = true;
</syntaxHighlight>
to your system configuration.
=== Installed apps don’t show up in Ubuntu's/GNOME's "Show Applications" ===
Consider some of the workarounds here: https://github.com/nix-community/home-manager/issues/1439.
=== Workaround with <code>home on tmpfs</code> and standalone installation ===
home-on-tmpfs users who installed home-manager standalone may meet problems that cannot load configs after reboot, caused by auto cleaning symlink under the toplevel of the home directory. You need to ensure <code>/home/<user>/.nix-profile</code> exists since the standalone install will not act symlink while the system boots.
If your toplevel of home is on tmpfs, one possible workaround is manually write <code>activationScripts</code> to link the directory:
<syntaxHighlight lang="nix">
  system.activationScripts = {
    # workaround with tmpfs as home and home-manager, since it not preserve
    # ~/.nix-profile symlink after reboot.
    profile-init.text =
      ''
        ln -sfn /home/${user}/.local/state/nix/profiles/profile /home/${user}/.nix-profile
      '';
  };
</syntaxHighlight>
Other files may also need to manually symlink in this case.
== Templates ==
* https://github.com/juspay/nix-dev-home A home-manager template providing useful tools & settings for Nix-based development.
== Alternatives ==


=== Alternatives ===
* [[Wrappers vs. Dotfiles]] shows how (per-user) wrapper scripts can be used in place of dotfiles in the user's home directory
* [[Wrappers vs. Dotfiles]] shows how (per-user) wrapper scripts can be used in place of dotfiles in the user's home directory
* [https://github.com/viperML/wrapper-manager wrapper-manager], an implementation of the idea above using the module system
== See also ==
* Starting from a machine with a minimal freshly installed NixOS ISO (KDE Plasma version), this video outlines the basics of using Home Manager as of 2021: [http://enia.cc/r/wilt-nixos-install-home-manager Wil T's "''NixOS Installation Guide''" (Home Manager section starts at 27:22)]
[[Category:Software]][[Category:Home Manager]]

Latest revision as of 08:22, 26 October 2024

Home Manager is a system for managing a user environment using the Nix package manager. In other words, Home Manager lets you

  • install software declaratively in your user profile, rather than using nix-env
  • manage dotfiles in the home directory of your user.

Home Manager has many options, which can look daunting at first, but most of those options only boil down to creating some dotfiles and installing some software in a way similar way to nix-env.

Note: Before attempting to use Home Manager please read the warning.

Configuration

Home Manager can be configured as a user in ~/.config/home-manager/home.nix or as a module inside configuration.nix.

Installation as a user

Follow the official guide

Your configuration is stored in ~/.config/home-manager/home.nix. Each time you modify it, rerun home-manager switch for changes to have effect.

Note that to work correctly, home-manager needs your shell to source ~/.nix-profile/etc/profile.d/hm-session-vars.sh. The most convenient way to do so is to have home-manager manage your whole shell configuration, eg programs.bash.enable = true; or programs.zsh.enable = true;. But in this case your whole bashrc is managed with Home Manager: the years of customization you accumulated in your former .bashrc must be migrated to Home Manager options, which may take some time. The quick and dirty way to do the migration is to move your bashrc to some other location and source it from Home Manager:

{ pkgs, ...}: {
  programs.bash = {
    enable = true;
    bashrcExtra = ''
      . ~/oldbashrc
    '';
  };
}

Usage as a NixOS module

Here is a nixos module template you can use:

{ config, pkgs, ... }:
let
  home-manager = builtins.fetchTarball "https://github.com/nix-community/home-manager/archive/master.tar.gz";
in
{
  imports = [
    (import "${home-manager}/nixos")
  ];

  home-manager.users.my_username = {
    /* The home.stateVersion option does not have a default and must be set */
    home.stateVersion = "18.09";
    /* Here goes the rest of your home-manager config, e.g. home.packages = [ pkgs.foo ]; */
  };
}

It can either be incorporated in /etc/nixos/configuration.nix or be placed in a standalone file and imported in configuration.nix: imports = [ ./thefile.nix ].

Whenever you change you home-manager configuration, you must rerun nixos-rebuild switch. With this method, changing the configuration of an unprivileged user requires to run a command as root.

Usage as a NixOS module in a Flake

Here is the skeleton of how to add Home Manager as a module to your system(s) via your flake:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
    home-manager = {
      url = "github:nix-community/home-manager/release-24.05";
      inputs.nixpkgs.follows = "nixpkgs"
    };
  };
  outputs = { self, nixpkgs, home-manager, ... }@inputs:
    nixosConfigurations.ExampleMachine = nixosConfiguration "ExmapleMachine"
      system = "x86_64-linux";
      modules = [
          ./configuration.nix
          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.your-username = import ./home.nix;
        };
      ];
    };
  };
}

Here's an example of home manager configuration in ./home.nix

{ config, pkgs, ... }:

{
  # Home Manager needs a bit of information about you and the
  # paths it should manage.
  home.username = "your-username";
  home.homeDirectory = "/home/your-username";

  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "24.05";

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}

Of course you'll probably want to keep more stuff in there than just a state version, but the state version is required.

The downside to doing it this way over the User config is that you have to do a full system rebuild; the home manager config is part of the full system, and so must be built as root or at least a trusted user.

Usage

Using Home Manager as a declarative version of nix-env

Nix-env has problematic behavior due to its imperative nature. For example, after installing java 8 with nix-env -i jdk8, running nix-env --upgrade upgrades java to 10 despite the fact that we initially explicitly requested java 8.

Installing software with Home-manager avoids this problem:

{ pkgs, ...}: {
  home.packages = [ pkgs.jdk8 ];
}

It is a perfectly valid use case for home-manager to only install software with home.packages without managing dotfiles at all.

Usage on non-NixOS Linux

Home Manager has an option to automatically set some environment variables that will ease usage of software installed with nix on non-NixOS linux (fixing local issues, settings XDG_DATA_DIRS, etc.):

{ pkgs, ...}: {
  targets.genericLinux.enable = true;
}

Managing your dotfiles

Home Manager has options to configure many common tools. As an example, adding the following

  programs.git = {
    enable = true;
    userName  = "my_git_username";
    userEmail = "my_git_username@gmail.com";
  };

will make Home Manager generate a .config/git/config file for you.

Even for programs for which Home Manager doesn't have configuration options, you can use it to manage your dotfiles directly, e.g.

  xdg.configFile."i3blocks/config".source = ./i3blocks.conf;
  home.file.".gdbinit".text = ''
      set auto-load safe-path /nix/store
  '';

This will create symlink $XDG_CONFIG_HOME/i3blocks/config and ~/.gdbinit.

Note: In both ways ("source" and "text"), the symlink points to a target in /nix/store. The difference is that, "source" would overwrite the content of the dot file, while "text" would add the text to the dot file that may also be affected in other places.

You have the whole list of the options available in home-manager here

Examples

FAQ

I cannot set GNOME or Gtk themes via home-manager

If you get an error about ca.desrt.conf or dconf.service on NixOS, add

programs.dconf.enable = true;

to your system configuration.

Installed apps don’t show up in Ubuntu's/GNOME's "Show Applications"

Consider some of the workarounds here: https://github.com/nix-community/home-manager/issues/1439.

Workaround with home on tmpfs and standalone installation

home-on-tmpfs users who installed home-manager standalone may meet problems that cannot load configs after reboot, caused by auto cleaning symlink under the toplevel of the home directory. You need to ensure /home/<user>/.nix-profile exists since the standalone install will not act symlink while the system boots.

If your toplevel of home is on tmpfs, one possible workaround is manually write activationScripts to link the directory:

  system.activationScripts = {
    # workaround with tmpfs as home and home-manager, since it not preserve
    # ~/.nix-profile symlink after reboot.
    profile-init.text =
      ''
        ln -sfn /home/${user}/.local/state/nix/profiles/profile /home/${user}/.nix-profile
      '';
  };

Other files may also need to manually symlink in this case.

Templates

Alternatives

  • Wrappers vs. Dotfiles shows how (per-user) wrapper scripts can be used in place of dotfiles in the user's home directory
  • wrapper-manager, an implementation of the idea above using the module system

See also