WSL x home-manager で dotfiles を管理する - 4手法の比較と使用方法 -
はじめに
Nix は高い再現性が特徴のパッケージマネージャーであり、home-manager は Nix を利用したユーザー環境の管理ツールです。
ここ最近、Nix を利用した開発環境を構築しています。
その過程で、git
の様な大半のプロジェクトで共通して利用するツールを楽に Nix で管理したいと思い、home-manager を導入しました。
これは私の感想ですが...
公式マニュアルに git
などの設定例が記述されていますが、「初見のパッケージに対してどの様に設定を書いていけばよいのか?」が分かりにくいと感じました。
そのため、本記事では git
の導入を例として、4つの導入方法の使い方・挙動の違いを解説していきます。
home.packages
programs.<name>
home.file.<name>.source
home.file.<name>.text
対象読者
- Nix 導入済み
-
Nix入門
、Nix入門: ハンズオン編
読了済み
検証環境
- 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
・公式マニュアル
・公式マニュアル(オプション解説)
・Home Manager - Option Search(home-manager オプション検索)
・NixOS Search - Packages(pkgs 検索)
・home-manager を解説されている記事
home-manager の準備
インストール
複数の方法が用意されていますが、WSL 環境の方は Standalone installation
一択となります。
以下を1行ずつ実行します。
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
に基づいて環境がビルド&アクティベートされます。
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
パッケージを導入していない状態を見てみましょう。
{ config, pkgs, ... }:
{
home.username = "ryu";
home.homeDirectory = "/home/ryu";
home.stateVersion = "25.05";
programs.home-manager.enable = true;
}
環境をアクティベートすると、当然ながら git
コマンドは Nix 以外の通常の方法でインストールした git
を利用している状態です。
$ home-manager switch
$ which git
/usr/bin/git
方法1 home.packages - パッケージの導入
まずは、Nix で git
を使えるようにする最も基本的な方法から見ていきます。
home.packages
に利用したいパッケージを記述します。
{ config, pkgs, ... }:
{
home.username = "ryu";
home.homeDirectory = "/home/ryu";
home.stateVersion = "25.05";
home.packages = [
pkgs.git
];
programs.home-manager.enable = true;
}
無事に Nix で管理された git
が使えるようになりました。
$ home-manager switch
$ which git
/home/ryu/.nix-profile/bin/git
どこの .gitconfig
が参照された状態になっているかを確認してみます。
$ 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>
を利用します。
{ 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
はどうなったでしょうか。
$ 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/config
は home.nix
により生成されています。
一方、/home/ryu/.gitconfig
は元からあったファイルです。
設定ファイルが重複している状態なので、後者を削除します。
(ここでは削除していますが、リネーム等でバックアップしておく方が安全です。)
$ 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
のコンフィグを置く場所に、既にファイルが存在した場合、以下の様なエラーとなります。
$ 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
を作成しておき、シンボリックリンクを作成する方法です。
{ 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.file = {
".gitconfig".source = git/.gitconfig;
};
方法4 home.file text - .gitconfig を home.nix にテキストで記述
.gitconfig
の内容をテキストで 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.file = {
".gitconfig".text = ''
[user]
name = MyName
email = MyMail
'';
};
実際の挙動を見てみると、環境のアクティベートにより .gitconfig
が生成&配置されていることが確認できます。
$ 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
で記述した userName
や userEmail
はどこから出てきたのでしょうか?
各パラメータを調べる 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 で利用可能なオプションを検索できます。
B. 公式マニュアルで検索する
Home Manager - Option Search で確認したオプションは公式マニュアルでも確認できます。
C. git.nix ファイルを読み解く
Home Manager - Option Search や公式マニュアルで programs.git.enable
を確認すると、下側に Declared by: <home-manager/modules/programs/git.nix>
というリンクがあります。
git の様にオプションの種類が多い、かつ、類似した名前が多い(検索で絞り込みにくい)パッケージの場合、nix ファイルを直接読んだ方がどんなパラメータがあるかを網羅的に把握しやすいと個人的には思いました。
101 行目以降の options
で定義されているパラメータが、home.nix
の programs.git
で利用可能なパラメータです。
サンプル1 userName
例えば、userName
を見ると、デフォルトは null であり、str 型が想定されていると分かります。
また、description
も貴重な情報になるでしょう。
options = {
programs.git = {
...
userName = mkOption {
type = types.nullOr types.str;
default = null;
description = "Default user name to use.";
};
...
サンプル2 extraConfig
もっと複雑なパラメータも確認してみます。
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
を例として、.gitconfig
と nix.home
における記述方法を比較してみます。
なお設定する値は、下記
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
git config --global core.whitespace trailing-space,space-before-tab,indent-with-non-tab
[core]
whitespace = trailing-space,space-before-tab,indent-with-non-tab
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
を再作成しています。
$ 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 で利用可能なパッケージを検索できます。
例えば、vim
で探すと以下の様になります。
pkgs.vim
で利用可能だと判断できます。
この時点で、方法2以外ならどの方法でも導入可能だと分かります。
- 方法1
home.packages
- 方法3
home.file.<name>.source
- 方法4
home.file.<name>.text
一方、方法2は home-manager が提供している手法ですので、home-manager のオプションを調べる必要があります。
今回は見つかったので、方法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
Home Manager Option Search というサイトでHome Managerのオプションを検索することができます!ぜひ確認してみてください!
おお!とても調べやすいです!
教えてくださりありがとうございます