🏵

WSL x home-manager で dotfiles を管理する - 4手法の比較と使用方法 -

に公開
2

はじめに

Nix は高い再現性が特徴のパッケージマネージャーであり、home-manager は Nix を利用したユーザー環境の管理ツールです

ここ最近、Nix を利用した開発環境を構築しています。
その過程で、git の様な大半のプロジェクトで共通して利用するツールを楽に Nix で管理したいと思い、home-manager を導入しました。

これは私の感想ですが...
公式マニュアルに git などの設定例が記述されていますが、「初見のパッケージに対してどの様に設定を書いていけばよいのか?」が分かりにくいと感じました。

そのため、本記事では git の導入を例として、4つの導入方法の使い方・挙動の違いを解説していきます

  1. home.packages
  2. programs.<name>
  3. home.file.<name>.source
  4. home.file.<name>.text

対象読者

  • Nix 導入済み
  • Nix入門Nix入門: ハンズオン編 読了済み

https://zenn.dev/asa1984/books/nix-introduction

https://zenn.dev/asa1984/books/nix-hands-on

検証環境

  • Windows 11
  • WSL2
    • Ubuntu 22.04.5 LTS
  • nix (Determinate Nix 3.8.2) 2.30.1
  • home-manager 25.11-pre
詳細
> wsl -l -v
  NAME              STATE           VERSION
  NixEnv            Running         2

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.5 LTS
Release:        22.04
Codename:       jammy

$ nix --version
nix (Determinate Nix 3.8.2) 2.30.1

$ home-manager --version
25.11-pre

$ nix-channel --list
home-manager https://github.com/nix-community/home-manager/archive/master.tar.gz

参考文献

・公式 GitHub
https://github.com/nix-community/home-manager

・公式マニュアル
https://nix-community.github.io/home-manager/index.xhtml

・公式マニュアル(オプション解説)
https://nix-community.github.io/home-manager/options.xhtml

・Home Manager - Option Search(home-manager オプション検索)
https://home-manager-options.extranix.com/

・NixOS Search - Packages(pkgs 検索)
https://search.nixos.org/packages

・home-manager を解説されている記事
https://blog.tomoyukim.net/entry/nix-home-manager/

https://qiita.com/suin/items/809236c1a6235ca012d7

https://zenn.dev/kuu/articles/20250204_introduce-home-manager

home-manager の準備

インストール

複数の方法が用意されていますが、WSL 環境の方は Standalone installation 一択となります。

https://nix-community.github.io/home-manager/index.xhtml#sec-install-standalone

以下を1行ずつ実行します。

bash
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
nix-channel --update
nix-shell '<home-manager>' -A install

home.nix と環境のアクティベート

インストール作業により、以下のディレクトリに home.nix が生成されます。

~/.config/home-manager/home.nix

home.nix でユーザー環境にて利用したいパッケージを指定したり、パッケージのオプションを設定できます

そして、以下のコマンドで home.nix に基づいて環境がビルド&アクティベートされます。

bash
home-manager switch

さて、次は実際に git などの設定を home.nix に記述していきます。

以降は git の導入を例として、各種設定方法を解説していきます

主なパッケージ導入方法の特徴・使い分け

導入方法 使い所
1 home.packages パッケージ導入だけしたい
2 programs.<name> パッケージ導入と設定ファイル生成をまとめて行いたい
3 home.file.<name>.source 既存の設定ファイルをシンボリックリンクで流用したい
4 home.file.<name>.text 設定ファイルの内容をテキストで home.nix 一か所に記述したい

所感

設定が不要なパッケージは home.packages 、設定が必要なら programs.<name> or home.file.<name>.source が良さそうに思います。

programs.<name>home.file.<name>.source は好みの問題ですが、より確実なのは home.file.<name>.source だと感じました

programs.<name> は home-manager 側が良い感じに設定ファイルを生成します、うがった見方をすると、home-manager の処理に起因したエラーが起こるリスクがあると言えます。)

home.file.<name>.text は設定ファイルの数が増えると可読性が落ちるので、home.file.<name>.source の方が適度に分割管理できて扱いやすいと思いました。

パッケージ未導入の挙動を確認

home.nix の編集で何が変化したかを分かりやすくするために、まずは git パッケージを導入していない状態を見てみましょう。

home.nix
{ config, pkgs, ... }:

{
  home.username = "ryu";
  home.homeDirectory = "/home/ryu";

  home.stateVersion = "25.05";

  programs.home-manager.enable = true;
}

環境をアクティベートすると、当然ながら git コマンドは Nix 以外の通常の方法でインストールした git を利用している状態です。

bash
$ home-manager switch
$ which git
/usr/bin/git

方法1 home.packages - パッケージの導入

まずは、Nix で git を使えるようにする最も基本的な方法から見ていきます。

home.packages に利用したいパッケージを記述します

home.nix
{ config, pkgs, ... }:

{
  home.username = "ryu";
  home.homeDirectory = "/home/ryu";

  home.stateVersion = "25.05";

  home.packages = [
    pkgs.git
  ];

  programs.home-manager.enable = true;
}

無事に Nix で管理された git が使えるようになりました。

bash
$ home-manager switch
$ which git
/home/ryu/.nix-profile/bin/git

どこの .gitconfig が参照された状態になっているかを確認してみます。

bash
$ git config --list --show-origin
file:/home/ryu/.gitconfig       user.name=MyName
file:/home/ryu/.gitconfig       user.email=MyMail

非 Nix 環境で git をインストールした時に使っていた .gitconfig が参照されています

次は、この .gitconfig も home-manager で管理してみます。

方法2 programs.git - パッケージの導入 & 設定

パッケージの導入と同時に、config も設定したい場合、programs.<package name> を利用します

home.nix
{ config, pkgs, ... }:

{
  home.username = "ryu";
  home.homeDirectory = "/home/ryu";

  home.stateVersion = "25.05";

  programs.git = {
    enable = true;
    userName = "MyNixName";
    userEmail = "MyEmail@example.com";
  };

  programs.home-manager.enable = true;
}

さて、これで .gitconfig はどうなったでしょうか。

bash
$ git config --list --show-origin
file:/home/ryu/.config/git/config       user.email=MyEmail@example.com
file:/home/ryu/.config/git/config       user.name=MyNixName
file:/home/ryu/.gitconfig       user.name=MyName
file:/home/ryu/.gitconfig       user.email=MyMail

/home/ryu/.config/git/confighome.nix により生成されています
一方、/home/ryu/.gitconfig は元からあったファイルです。

設定ファイルが重複している状態なので、後者を削除します。
ここでは削除していますが、リネーム等でバックアップしておく方が安全です。)

bash
$ rm ~/.gitconfig
$ git config --list --show-origin
file:/home/ryu/.config/git/config       user.email=MyEmail@example.com
file:/home/ryu/.config/git/config       user.name=MyNixName

既存の config ファイルと衝突した場合の挙動

home-manager が git のコンフィグを置く場所に、既にファイルが存在した場合、以下の様なエラーとなります。

bash
$ home-manager switch
…
Activating checkLinkTargets
Existing file '/home/jdoe/.config/git/config' is in the way
Please move the above files and try again

公式マニュアルより

To configure programs and services Home Manager must write various things to your home directory. To prevent overwriting any existing files when switching to a new generation, Home Manager will attempt to detect collisions between existing files and generated files. If any such collision is detected the activation will terminate before changing anything on your computer.

方法3 home.file source - .gitconfig のシンボリックリンク

予め .gitconfig を作成しておき、シンボリックリンクを作成する方法です

home.nix
{ config, pkgs, ... }:

{
  home.username = "ryu";
  home.homeDirectory = "/home/ryu";

  home.stateVersion = "25.05";

  home.packages = [
    pkgs.git
  ];

  home.file = {
    ".gitconfig".source = git/.gitconfig;
  };

  programs.home-manager.enable = true;
}

この例では、git はパッケージを導入するだけなので、home.packages を利用しています。

home.file.<FileName>.source = <FilePath> でどのファイルのシンボリックリンクを作成するかを指定します

home.nix
  home.file = {
    ".gitconfig".source = git/.gitconfig;
  };

方法4 home.file text - .gitconfig を home.nix にテキストで記述

.gitconfig の内容をテキストで home.nix に直接記述する方法です

home.nix
{ config, pkgs, ... }:

{
  home.username = "ryu";
  home.homeDirectory = "/home/ryu";

  home.stateVersion = "25.05";

  home.packages = [
    pkgs.git
  ];

  home.file = {
    ".gitconfig".text = ''
      [user]
        name = MyName
        email = MyMail
    '';
  };

  programs.home-manager.enable = true;
}

home.file.<FileName>.text = <ConfigText><FileName> の中身をテキストで直接記述できます

home.nix
  home.file = {
    ".gitconfig".text = ''
      [user]
        name = MyName
        email = MyMail
    '';
  };

実際の挙動を見てみると、環境のアクティベートにより .gitconfig が生成&配置されていることが確認できます。

bash
$ cat /home/ryu/.gitconfig
cat: /home/ryu/.gitconfig: No such file or directory

$ home-manager switch

$ cat /home/ryu/.gitconfig
[user]
  name = MyName
  email = MyMail

(おまけ解説)programs.git のパラメータの調べ方

方法2 にて programs.git で記述した userNameuserEmail はどこから出てきたのでしょうか?

各パラメータを調べる 3 つの方法を解説します。

  • A. Home Manager - Option Search で検索する
  • B. 公式マニュアルで検索する
  • C. git.nix ファイルを読み解く

基本的には A. Home Manager - Option Search が調べやすくて良いと思います

「一次情報を探る方法」という観点で B. 公式マニュアルで検索するC. git.nix ファイルを読み解くの方法も紹介します。

A. Home Manager - Option Search で検索する

以下のサイトで home-manager で利用可能なオプションを検索できます。

https://home-manager-options.extranix.com/

https://github.com/mipmip/home-manager-option-search

Home Manager - Option Search で git を検索した結果

B. 公式マニュアルで検索する

Home Manager - Option Search で確認したオプションは公式マニュアルでも確認できます

https://nix-community.github.io/home-manager/options.xhtml#opt-programs.git.enable

公式マニュアルで git を検索した結果

C. git.nix ファイルを読み解く

Home Manager - Option Search や公式マニュアルで programs.git.enable を確認すると、下側に Declared by: <home-manager/modules/programs/git.nix> というリンクがあります。

git の様にオプションの種類が多い、かつ、類似した名前が多い(検索で絞り込みにくい)パッケージの場合、nix ファイルを直接読んだ方がどんなパラメータがあるかを網羅的に把握しやすいと個人的には思いました。

https://github.com/nix-community/home-manager/blob/master/modules/programs/git.nix

101 行目以降の options で定義されているパラメータが、home.nixprograms.git で利用可能なパラメータです

サンプル1 userName

例えば、userName を見ると、デフォルトは null であり、str 型が想定されていると分かります。
また、description も貴重な情報になるでしょう。

git.nix
  options = {
    programs.git = {
      ...
      userName = mkOption {
        type = types.nullOr types.str;
        default = null;
        description = "Default user name to use.";
      };
      ...

サンプル2 extraConfig

もっと複雑なパラメータも確認してみます。

git.nix
  options = {
    programs.git = {
      ...
      extraConfig = mkOption {
        type = types.either types.lines gitIniType;
        default = { };
        example = {
          core = {
            whitespace = "trailing-space,space-before-tab";
          };
          url."ssh://git@host".insteadOf = "otherhost";
        };
        description = ''
          Additional configuration to add. The use of string values is
          deprecated and will be removed in the future.
        '';
      };
      ...

情報量が増えて分かりにくそうですが、やる事は存外単純です。

example に記載されている core whitespace を例として、.gitconfignix.home における記述方法を比較してみます。

なお設定する値は、下記 git のドキュメントの例をそのまま使用しました。

https://git-scm.com/book/ja/v2/Git-のカスタマイズ-Git-の設定

比較

詳細な定義は省きますが、見た目で記載ルールが分かるかと思います。

git のドキュメントで .gitconfig での記述方法を調べれば、home.nix での記述方法を推測できるでしょう

# .gitconfig
[core]
	whitespace = trailing-space,space-before-tab,indent-with-non-tab

# home.nix
    extraConfig = {
      core = {
        whitespace = "trailing-space,space-before-tab,indent-with-non-tab";
      };
    };

参考までに、検証時のコードを以降に記載します。

.gitconfig

bash
git config --global core.whitespace trailing-space,space-before-tab,indent-with-non-tab
.gitconfig
[core]
	whitespace = trailing-space,space-before-tab,indent-with-non-tab

home.nix

home.nix
  programs.git = {
    enable = true;
    userName = "MyNixName";
    userEmail = "MyEmail@example.com";
    extraConfig = {
      core = {
        whitespace = "trailing-space,space-before-tab,indent-with-non-tab";
      };
    };
  };
設定反映の確認

検証のため、先ほどのセッションで削除した .gitconfig を再作成しています。

bash
$ git config --list --show-origin
file:/home/ryu/.config/git/config       core.whitespace=trailing-space,space-before-tab,indent-with-non-tab
file:/home/ryu/.gitconfig       core.whitespace=trailing-space,space-before-tab,indent-with-non-tab

(おまけ解説) git 以外にどんなパッケージが導入可能か調べる

こちらのサイトで Nix で利用可能なパッケージを検索できます

https://search.nixos.org/packages

例えば、vim で探すと以下の様になります。

nix search で vim を検索した結果

pkgs.vim で利用可能だと判断できます。

この時点で、方法2以外ならどの方法でも導入可能だと分かります。

  • 方法1 home.packages
  • 方法3 home.file.<name>.source
  • 方法4 home.file.<name>.text

一方、方法2は home-manager が提供している手法ですので、home-manager のオプションを調べる必要があります

https://home-manager-options.extranix.com/

Home Manager - Option Search で vim を検索した結果

今回は見つかったので、方法2でも vim を管理可能だと判断できます。

  • 方法2 programs.<name>

更新履歴

2025/8/8

コメントにて Home Manager - Option Search というサイトを教えていただいた。
home-manager で利用可能なオプションを簡易に検索できる。

  • セッション(おまけ解説)programs.git のパラメータの調べ方Home Manager - Option Searchを追加
  • 参考文献に当該サイトを追加
  • 要素追加に伴い各セッションの細かい文言を調整
コメント(敬称略)
satler

Home Manager Option Search というサイトでHome Managerのオプションを検索することができます!ぜひ確認してみてください!

Discussion

satlersatler

Home Manager Option Search というサイトでHome Managerのオプションを検索することができます!ぜひ確認してみてください!

trifoliumtrifolium

おお!とても調べやすいです!
教えてくださりありがとうございます