Featured image of post Nix Home Managerでdotfilesを管理

Nix Home Managerでdotfilesを管理

目次

Background

  • dotfilesをnixに半分移行した
  • 宣言的一発で環境再現ができるから
  • ただし、GPU系の処理が厳しいので、NixOSは使わない
  • 既存のUbuntu上でNixのHome Managerでdotfilesの管理をする構成

Nixとは

  • Nixはパッケージマネージャーであり、同時にプログラミング言語
  • 通常のパッケージマネージャー(apt、brewなど)との最大の違いは宣言的である点
  • 「このパッケージをインストールしてほしい」と書いておけば、Nixがその状態を実現してくれる
  • また、パッケージは/nix/store/以下にハッシュ付きのパスで格納される -そのたため、バージョンが異なる同一パッケージを共存させられるし、環境が壊れても以前の状態にロールバックできる
1
2
/nix/store/abc123-ripgrep-14.1.0/
/nix/store/def456-ripgrep-13.0.0/  ← 古いバージョンも共存できる

NixパッケージのソースはnixpkgsというGitHubリポジトリで管理されており、パッケージが揃っている。

Flakeとは

FlakeはNixのプロジェクト管理の仕組み。flake.nixというファイル1つでプロジェクトの依存関係と出力を定義する。

1
2
3
4
5
6
7
8
9
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
  };

  outputs = { nixpkgs, ... }: {
    # 定義など
  };
}

inputsは依存するリポジトリやパッケージセットを宣言する。 outputsはそのflakeが外部に提供するもの(パッケージ、設定、開発環境など)を返す関数。

Flakeを使うとflake.lockが生成され、依存リポジトリの正確なコミットハッシュが記録される。 これによりどのマシンでも同一の環境を再現できる。

Flake登場以前は、nixpkgsのバージョンが実行環境によって変わってしまい、再現性に難があった。 現在はFlakeが事実上の標準となっている。

Home Managerとは

Home ManagerはNixをベースにしたユーザー環境管理ツール。

Nixは本来OSレベルのパッケージ管理が得意だが、Home Managerを使えばユーザーのホームディレクトリ以下の管理もNixで行える。具体的には:

  • ~/.config/以下の設定ファイルの配置
  • ~/以下のdotfileの配置
  • ユーザー向けパッケージのインストール

NixOSはOS全体をNixで管理するディストリビューションだが、Home ManagerはUbuntuやmacOSなど既存のOSの上でそのまま使えるのが特徴。

flake.nix

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nixpkgs, nixpkgs-stable, home-manager, ... }:
    let
      system = "x86_64-linux";
      pkgs = nixpkgs.legacyPackages.${system};
      pkgs-stable = nixpkgs-stable.legacyPackages.${system};
    in {
      homeConfigurations."myhome" = home-manager.lib.homeManagerConfiguration {
        inherit pkgs;

        extraSpecialArgs = {
          inherit pkgs-stable;
        };

        modules = [ ./nix/home.nix ];
      };
    };
}

基本はnixpkgs-unstableを使うが、一部のパッケージ(tmux 3.4など)はstableから取る。 stableのパッケージセットはpkgs-stableという名前で_module.args経由でモジュールに渡している。

inputs.nixpkgs.follows = "nixpkgs"は、Home Managerがインターナルでもつnixpkgsをこちらのnixpkgsに統一する指定。これがないと2つの異なるnixpkgsが混在して余計なビルドが走ることがある。

.#myhomeの意味

home-manager switch --flake .#myhome.#myhomeはFlakeのアドレス記法。

1
2
3
.          # カレントディレクトリのflake.nixを参照
 #         # セパレータ
  myhome     # outputs内のキー名

flake.nixoutputsにはhomeConfigurations."myhome"というキーで設定を登録してある。 .#myhomeはそれを指定している。

複数ユーザーや複数マシンの設定を1つのflakeに共存させることも可能。

1
2
3
4
homeConfigurations = {
  "me@desktop"        = ...; 
  "me@server" = ...;  
};

設定ファイルの配置

Home Managerのhome.fileを使えば、設定ファイルをホームディレクトリ以下の任意のパスにシンボリックリンクとして配置可能。

1
2
3
4
home.file = {
  ".gitconfig".source = ../../config/git/.gitconfig;
  ".config/fish/config.fish".source = ../../config/fish/config.fish;
};

Neovimのinit.luaなど、プラグインマネージャーが実行時に書き換えるファイルはmkOutOfStoreSymlinkでNix storeを経由せず直接リンクを張る。Nix storeは読み取り専用なので、書き換えが発生するファイルは通常の.sourceでは壊れてしまう。

1
2
".config/nvim/init.lua".source = config.lib.file.mkOutOfStoreSymlink
  "${config.home.homeDirectory}/dotfiles/config/nvim/init.lua";

direnv連携

shell.nixでdirenvとnix-direnvを有効にしている。

1
2
3
4
programs.direnv = {
  enable = true;
  nix-direnv.enable = true;
};

direnvはディレクトリに入ったとき自動で環境変数を設定するツール。 nix-direnvはその拡張で、flake.nixを持つプロジェクトディレクトリにcdするだけで そのプロジェクト専用のNix環境が自動で有効になる。

AIツール

ai.nixでは最近増えたAI CLIツールをまとめて管理している。

1
2
3
4
5
6
home.packages = with pkgs; [
  codex
  claude-code
  gemini-cli
  openclaw
];

claude-codeはunfreeパッケージなので、home.nixで許可リストに追加している。

1
2
3
4
nixpkgs.config.allowUnfreePredicate = pkg:
  builtins.elem (pkgs.lib.getName pkg) [
    "claude-code"
  ];

使い方

初回セットアップは以下のコマンド。

Home Manager自体がまだ入っていなくても、nix runでHome Managerを一時的に起動して適用できる。

1
nix run home-manager -- switch --flake .#myhome

2回目以降は

1
home-manager switch --flake .#myhome

これだけでパッケージのインストールと設定ファイルの配置が完了する。

注意点

  • nixはstoreですべてが管理されてしまうため、コンパイルやリンクで問題が起きがち
  • 特に、nixのpythonやtoolを使うと発生する
  • そのため、コンパイラーやリンカー、pythonなどはubuntuのものを使うようにしている
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash

# CUDA
VENV_NVIDIA="${SCRIPT_DIR}/.venv/lib/python3.12/site-packages/nvidia"
export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:/usr/local/cuda/lib64:${VENV_NVIDIA}/cu13/lib:${VENV_NVIDIA}/nvjitlink/lib:${VENV_NVIDIA}/cublas/lib:${VENV_NVIDIA}/cudnn/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"

# PATH 先頭に /usr/bin を置いて as/ld も確実にシステム版を使う
export PATH="/usr/bin:/usr/local/bin:${PATH}"
export CC=/usr/bin/gcc
export CXX=/usr/bin/g++

まとめ

  • Nixは宣言的・再現性のあるパッケージ管理を実現する
  • FlakeはNixプロジェクトの依存関係をflake.lockでピン留めし、再現性を保証する
  • Home ManagerはNixをユーザー環境の管理に応用したツールで、既存OSの上でも動く
  • パッケージ管理と設定ファイル管理を一箇所で宣言的に扱えるため、ある程度は新しいマシンへの移行が容易
最終更新 May 09, 2026 19:50 +0900
Built with Hugo
テーマ StackJimmy によって設計されています。