macOS・Linux・WSLで、いつもの開発環境を再現する。
Nix Flakes・nix-darwin・Home Managerで管理する個人用dotfilesです。 シェル、Neovim、開発ツール、AIエージェントをまとめて管理し、 macOSのシステム設定とホーム環境は独立して更新できます。
| 環境 | 管理するもの | 適用コマンド |
|---|---|---|
| macOS / Linux / WSL | シェル・エディター・CLI・AIエージェント | nix-switch |
| macOSのみ | Homebrewのアプリ・フォント・OS設定 | darwin-switch |
セットアップ · 日常の操作 · 設定を変更する · ドキュメント
- シェル — Zsh、fzf-tab、Starship、atuin、fzf、zoxide、direnv
- エディターとGit — Neovim、Git、delta、lazygit
- CLI — bat、eza、fd、ripgrep、yazi、gh、xh など
- ターミナル — Ghostty。macOSではAeroSpace・Karabinerも設定
- macOSのアプリ — Homebrewのformula・caskをnix-homebrewで宣言。Xcodeはxcodesで導入
- 開発ツール — Go、Rust、Node.js、Bun、pnpm、Python、uv、各種言語サーバー
- AIエージェント — Claude Code、Codex、Cursor CLI、OpenCode、Antigravity CLI、Grok、Herdr、Hunk
- 共通基盤 — エージェント向けルール・スキル・MCP設定、sopsによる機密情報の管理
導入するツールはホストごとのプリセットで選択します。
たとえばazureuserのLinux構成はRustを除外し、T3 Codeのサーバーはgem-aiだけに追加します。
このリポジトリは個人のユーザー名・ホスト名に合わせた構成です。
そのまま汎用インストーラーとして使うものではありません。
クローン先は~/dotfilesを前提とし、別の環境では
flake.nixとnix/hosts/のユーザー名・ホームディレクトリ・ホスト名を調整してください。
通常の Nix のマルチユーザー構成を使用します。 以下は Nix が未導入の環境向けです。既存の環境では再インストールせず、 Determinate Nix からの移行を確認してください。
sh <(curl --proto '=https' --tlsv1.2 -fsSL https://nixos.org/nix/install) --daemonシェルを開き直し、nix --versionでインストールを確認します。
numtide と satotek のキャッシュを登録して、ソースビルドを避けます。
macOS は初回の nix-darwin 適用後にシステム設定として管理します。
初回ビルド前、および Linux/WSL では管理者権限で /etc/nix/nix.conf に
次の設定を追加してください。既存の取得先・公開鍵は残し、同じ設定行に統合します。
experimental-features = nix-command flakes
extra-substituters = https://cache.numtide.com https://satotek.cachix.org
extra-trusted-substituters = https://cache.numtide.com https://satotek.cachix.org
extra-trusted-public-keys = niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g= satotek.cachix.org-1:/2yz7ZHPnRzW91UqChW6XmRSX2Tq0NrNPjKsIUppRFA=
Linux/WSL では変更後に sudo systemctl restart nix-daemon.service を実行します。
自分を trusted-users に追加しなくても、システム側で登録したキャッシュは使えます。
Azure CLI は github:satotek/azure-cli-nix の固定済みパッケージを使います。
配布側の nixpkgs input を上書きしないことで、3環境の公開済みキャッシュと一致させます。
git clone https://github.com/satotek/dotfiles.git ~/dotfiles
cd ~/dotfilesHome Managerの構成名は次から選びます。
| 構成名 | プラットフォーム | 用途 |
|---|---|---|
nosuke@nosuke-M5-MBP |
aarch64-darwin |
macOS |
nosuke@linux-x86_64 |
x86_64-linux |
汎用Linux |
nosuke@linux-aarch64 |
aarch64-linux |
汎用Linux |
nosuke@nosuke-windows |
x86_64-linux |
WSL |
stko23@stko23-windows |
x86_64-linux |
WSL |
azureuser@linux-x86_64 |
x86_64-linux |
Azure / 汎用Linux |
azureuser@linux-aarch64 |
aarch64-linux |
Azure / 汎用Linux |
azureuser@gem-ai |
x86_64-linux |
gem-ai |
macOSのシステム構成はdarwinConfigurations.nosuke-M5-MBPです。
すべての出力はnix flake showで確認できます。
macOS — システム層を適用してからホーム環境を適用します。
HomebrewアプリやmacOSの既定値も変更されるため、先にnix/nix-darwin/を確認してください。
Homebrew本体はnix-homebrewが導入するので、事前のインストールは不要です。
sudo nix run nix-darwin/master#darwin-rebuild -- \
switch --flake "path:$PWD#nosuke-M5-MBP"
nix run home-manager/master -- \
switch -b backup --flake "path:$PWD#nosuke@nosuke-M5-MBP"Linux / WSL — <home-configuration>を上の構成名に置き換えます。
nix run home-manager/master -- \
switch -b backup --flake "path:$PWD#<home-configuration>"既存の/opt/homebrewがある場合は、nix-homebrewが初回の適用で引き継ぎます。
tapは宣言したものだけにするため、/opt/homebrew/Library/Tapsが残っていると
適用が止まります。中のtapは宣言から作り直されるので、退避してから再実行してください。
宣言にないformula・caskは適用時にアンインストールされます(Homebrew)。
Linux / WSLでは、初回適用後にログインシェルをNixのZshへ一度だけ切り替えます。
OSのZshのままだと、Nixでビルドしたfzf-tabのモジュールがglibcの違いで読み込めません。
Home Managerは/etc/passwdを変更できないため手動で行い、未設定なら適用時に警告します。
echo ~/.nix-profile/bin/zsh | sudo tee -a /etc/shells
chsh -s ~/.nix-profile/bin/zshホーム環境の適用にsudoは不要です。-b backupは既存ファイルとリンクが
衝突した場合の退避用です。同名のバックアップがある場合は確認してから整理してください。
機密情報の復号を使うホストでは、機密情報の認証設定も必要です。
Gitのユーザー情報と任意のZsh上書き設定は、リポジトリ外で管理します。 既存ファイルがない場合にテンプレートをコピーし、自分の環境に合わせて編集してください。
cp -n ~/dotfiles/.config/git.local.example ~/.config/git.local
cp -n ~/dotfiles/.config/zsh.local.example ~/.config/zsh.local初回適用後はラッパーコマンドを利用できます。
cd ~/dotfiles
git pull
nix-switch| 変更したもの | 実行するコマンド |
|---|---|
| シェル、CLI、Neovim、エージェントなど | nix-switch |
| Homebrewのformula・cask、フォント、macOS設定 | darwin-switch(sudoが必要) |
| 両方 | darwin-switchの後にnix-switch |
nix-switchは現在のユーザー名とホスト名から構成を選びます。
ホスト名が構成名と一致しない環境では、対象を明示して適用してください。
home-manager switch --flake 'path:/home/azureuser/dotfiles#azureuser@linux-x86_64'新規ファイルは通常のGit flake入力に含まれません。
追加したパスだけをgit add -N <path>で認識させるか、
初回セットアップと同様にpath:$PWD#...を指定して検証します。
flake.nix
│
┌──────────────┴──────────────┐
│ │
darwinConfigurations homeConfigurations
(macOSのみ) (macOS / Linux)
│ │
nix/nix-darwin/ nix/home-manager/
│ │
Homebrew / フォント / シェル / エディター / CLI /
macOSの既定値 / sudo認証 エージェント / リポジトリ内の設定
│ │
darwin-switch nix-switch
sudo必須 sudo不要
macOS の Nix 本体・デーモン・キャッシュ設定は nix-darwin が管理します。
GC は既存の nh clean に集約し、ユーザーの古い世代は Home Manager の定期ジョブ、
macOS の system 世代・store は root の定期ジョブで整理します。
Linux/WSL の Nix デーモン設定は管理者が管理します。
Git、Zsh、Starship、direnv、zoxide、fzf、atuin、bat、eza、yazi、gh、
ripgrep、delta、Ghostty、Lazygitなどは、Home Managerのオプションから生成します。
変更後はnix-switchで適用します。ghのconfig.ymlのように生成したファイルは
読み取り専用になるので、gh config setなどアプリ側からは変更できません。
Lazygitのconfig.ymlはprograms.lazygit.settingsから生成され、適用時に
公式スキーマで検証されます。ページャーとして使うdeltaは、
Nixストアの絶対パスで参照します。
頻繁に直接編集したい設定には、Home Managerがリポジトリを参照する
シンボリックリンクを作ります。対象は.config/nvim、
Hunk・AeroSpace・Karabiner・OpenCode・Nix(nix.conf)の設定です。
これらには、編集直後にアプリケーションから読めるものと、再起動・再読み込み・
nix-switchが必要なものがあります。各モジュールの管理方法を確認してください。
macOSのGUIアプリと一部のformulaは、nix/nix-darwin/homebrew.nixに用途別に宣言します。
mpv・IINA・SVPのように連携して使うものはhomebrew-video.nixに分けています。
- brew本体とtap — nix-homebrewが管理します。brew本体は
flake.nixのbrew-srcで リリースのタグに固定し、サードパーティのtapもflake inputで固定します。brew tapで宣言にないtapは追加できません。 - 宣言にないパッケージ —
onActivation.cleanup = "uninstall"なので、宣言にない formula・caskはdarwin-switch時にアンインストールします。残したいものは先に宣言へ 追加してください。caskの関連設定・データを削除するzapは使いません。 - Nixとcaskの使い分け — 版を
flake.lockで決めたいアプリはNixで入れ、アプリ自身の 自動更新を切ります(Ghosttyなど)。アプリが自分で更新するものはcaskにします。 - 更新 — formulaと自動更新のないcaskは
brew upgradeで上げます。brew本体を上げるときはbrew-srcのタグを書き換え、nix flake update brew-srcの後にdarwin-switchします。 - Xcode — NixにもHomebrewにも載せず、
xcodesで導入と切り替えを行います。
次はGit管理しません。
~/.config/git.local~/.config/zsh.local~/.config/secrets~/.ssh/id_rsa(Azure DevOps用。ed25519非対応のためRSA)~/.ssh/id_rsa.pub$XDG_CACHE_HOME/zsh/
リポジトリで管理する機密情報はsecrets/*.yamlをsopsで暗号化し、
GCP Cloud KMSで復号します。
projects/nosuke-net/locations/global/keyRings/sops/cryptoKeys/dotfiles
各ホストで一度、Application Default Credentialsを設定します。
gcloud config set project nosuke-net
gcloud auth application-default login
gcloud auth application-default set-quota-project nosuke-net現在の出力先:
| 暗号化ファイル | 復号先 | 対象 |
|---|---|---|
secrets/agents.yaml |
~/.config/opencode/secrets/deepseek.key |
全環境 |
secrets/agents.yaml |
~/.config/opencode/secrets/google.key |
全環境 |
secrets/agents.yaml |
~/.dsh/.env |
全環境 |
secrets/cloudflare.yaml |
~/.config/cloudflare/cloudflare-infra.env |
macOSのみ |
OpenCode は {file:...} で復号済みファイルを読むため、キーは環境変数に載りません。
同じ provider で opencode auth login すると credential が優先され、sops のキーは
使われません。DeepSeek と Google は logout したままにします。
値を更新するときは sops でファイルを開いて編集し、nix-switch で配り直します。
sops secrets/agents.yaml
nix-switch漏洩した場合は、先にプロバイダ側でキーを失効・再発行し、そのあと sops の値を 更新します。
既存ファイルの暗号化先にKMSキーを追加した場合は、復号可能なマシンで 暗号化し直します。
sops updatekeys secrets/*.yaml平文の YAML をコミットしないよう、pre-commit が secrets/*.yaml に
ENC[ を要求します。
リポジトリ管理外のシェル用機密情報は~/.config/secretsへ置けます。対話的な zsh だけが読み、zsh -c には載せません。ファイルがあれば適用時に権限を 0600 に揃えます。
Zshプラグインはnixpkgsで取得し、zsh-deferでハイライトと入力候補を遅延読み込みします。
プロンプトはStarship、履歴検索はatuin、ファイル選択はfzf、Tab補完はfzf-tabが担当します。
Zshコードはnix/home-manager/programs/zsh/に分割し、Nix評価時に.zshrcへ
埋め込みます。Starship、direnv、fzf、zoxideの生成結果は$XDG_CACHE_HOME/zshに
キャッシュします。出力がパッケージだけで決まるatuinとnix-your-shellの初期化は、
ビルド時に生成します。プラグインのローダーもビルド時に生成・コンパイルします。
補完は自前のcompinitで初期化し、通常はcompinit -Cでキャッシュを利用します。
Home Manager適用時に補完キャッシュを無効化するため、新しいシェルで追加・更新に追従します。
主なキーバインド:
| キー | 動作 |
|---|---|
Ctrl-B |
Gitブランチをfzfで選択 |
Ctrl-G |
ghq / rootsのプロジェクトへ移動 |
Ctrl-R |
atuinで履歴を検索 |
Ctrl-T / Alt-C |
ファイルをfzfで選んで挿入 / ディレクトリへ移動 |
Ctrl-X → Ctrl-K |
プロセスをfzfで選択して終了 |
Tab |
fzf-tabで説明付きの補完候補を選択 |
↑ / ↓ |
入力中の文字列の前方一致で履歴を遡る / 進む |
行の編集はvi方式です。Escでコマンドモードに入り、コマンドモードのvで今の行をNeovimで開きます。
詳細はZshのキーバインドを参照してください。
エージェントのパッケージは主にllm-agents.nixオーバーレイから導入します。
設定はHome Managerで生成し、共通のMCP定義は
nix/home-manager/data/mcp-servers.nixに置きます。
Herdr本体はNixパッケージとして管理しています。aiロールのホストでは、Home Managerの適用時に
Claude Code、Codex、Cursor、Grok、OpenCodeのHerdr連携を生成し、セッション復元に必要なフックを設定します。
Herdrの新規ペインとscratch terminalはHome ManagerのNix製Zshを起動します。 OS標準ZshとNix製fzf-tabのバイナリモジュール間でglibcの不一致が起きるのを避けるためです。
Herdrのリモート運用とSSHポート転送は VMリモート作業手順を参照してください。
Home Managerのパッケージは用途別のプリセットに分け、プリセットをロールに束ねています。
ホストはnix/home-manager/roles.nixのselectでロールを選びます。
| プリセット | 用途 |
|---|---|
shell |
Zsh(nixpkgsプラグイン・fzf-tab)、Starship、direnv、zoxide、nix-index(comma) |
cli |
atuin、bat、eza、fd、ripgrep、yazi、btop、gh、xh、nix-your-shell、Herdr、hunk などの常用CLI |
git |
Git、delta、lazygit |
editor |
Neovim、rumdl |
terminal |
Ghostty。macOS だけで読む(platforms/darwin.nix) |
agents |
AIエージェント、スキル、MCP、Herdrとの連携 |
secrets |
SOPS と復号の activation |
cloud |
Azure CLI、Google Cloud SDK |
infra |
tenv、Terraform 言語サーバ、hadolint、lazydocker、psql |
go |
Go、gopls |
rust |
rustc、cargo、clippy、rustfmt、rust-analyzer |
node |
Node.js、Bun、pnpm、TypeScript、Web系の言語サーバ |
python |
Python、uv、ruff、basedpyright |
editor-lsp |
シェル、Lua、Markdown、YAML、Nix、TOML の言語サーバ |
media |
ffmpeg、Mermaid |
linux-desktop |
wl-clipboard、xclip(Linux のデスクトップ用。画面のない環境では動かない) |
| ロール | プリセット |
|---|---|
base |
shell、cli、git、editor |
dev |
editor-lsp、node、python、go、infra、cloud、media |
rust |
rust |
ai |
agents |
secrets |
secrets |
linux-desktop |
linux-desktop(今は選んでいるホストがない) |
| ホスト | ロール |
|---|---|
macOS(nosuke@nosuke-M5-MBP) |
base、dev、rust、ai、secrets |
nosuke@*(Linux、WSL) |
base、dev、rust、ai、secrets |
azureuser@*(Azure VM) |
base、dev、ai、secrets |
stko23@stko23-windows(業務用WSL) |
base、dev、rust |
よく使う検証:
# Nixの整形
nix fmt
# 現在のプラットフォームを検証
nix flake check
# 特定のHome Manager出力をビルド
nix build --no-link \
'.#homeConfigurations."nosuke@linux-x86_64".activationPackage'
# Zshスニペットの構文
for file in nix/home-manager/programs/zsh/*.zsh; do
zsh -n "$file"
done詳細なコマンドはメンテナンス用コマンドを参照してください。
dotbenchは対話型ZshとヘッドレスNeovimを1回ウォームアップした後、
既定で10回測定し、最小値・中央値・平均値・最大値を表示します。
dotbench
dotbench 30
dotbench --only zsh --runs 50 --warmup 2 --output before.json
dotbench --only zsh --warmup 2 --compare before.json
dotbench --only zsh --zsh "$HOME/.nix-profile/bin/zsh"
dotbench interactive --runs 10 --output before.json
dotbench interactive --compare before.json環境間または変更前後の比較には、バックグラウンド処理の影響を受けにくい
中央値を使います。通常のZsh計測はzsh -i -c exitの起動・終了時間であり、
プロンプト表示や遅延プラグインの読み込み完了、入力応答を直接測るものではありません。
--onlyで対象、--runsと--warmupで回数、--zshと--nvimで実行ファイルを指定できます。
JSONには生の時間(ナノ秒)とOS・CPU・ホスト・実行パス・バージョンを保存します。
--outputは既存ファイルを上書きしません。比較は中央値の増減率を表示し、環境の違いは警告します。
設定内容やシステム負荷の同一性までは確認しないため、条件を揃えて比較してください。
interactiveは擬似端末の中で自分の設定のZshを起動し、操作したときの待ち時間を測ります。
起動ファイルの最後にプロンプトの目印を出すフックを足すため、プロンプトの内容には依存しません。
| 項目 | 測る区間 |
|---|---|
first_prompt |
起動から最初のプロンプトが入力を受け付けるまで |
first_command |
起動直後に押したEnterが処理され、次のプロンプトが出るまで(遅延読み込みの待ちが現れる) |
command |
遅延読み込みが落ち着いた後、空のEnterから次のプロンプトまで |
exit |
Ctrl-Dからプロセスが終了するまで |
空行とCtrl-Dしか入力しないため、履歴は増えません。非ログインシェルで測り、
キー入力ごとの描画やTabの待ち時間は測りません。--outputと--compareは起動時間の計測と同じように使えます。
ヘルプはdotbench --helpを参照してください。Bash・Zsh・fishの補完はNixパッケージに同梱します。
Home Managerのprograms.nh.cleanで、ユーザーのプロファイル(home-managerと
home-manager-pathを入れるprofile)を毎週nh clean userで整理します。
最低2世代と直近7日分を残し、--no-gcrootsでdirenvなどの開発用GC rootは保持します。
| OS | 実行タイミング | 内容 |
|---|---|---|
| Linux | 毎週月曜0:00(systemd timer、停止中に過ぎた分は起動時に実行) | 世代整理、NixストアのGCと最適化 |
| macOS | 毎週日曜12:00 | 世代整理のみ(--no-gc) |
| macOS | 毎週日曜12:15 | nix-darwinのシステム世代を同じ条件で整理し、NixストアのGCと最適化 |
macOSのストアGCはroot権限で動くsystem側のnh clean profileに集約しています。
最適化(--optimise)は同じ内容のファイルをハードリンクでまとめ、ストアを15%ほど縮めます。
GitHub Actionsがflakeの入力を更新し、Linux用Home Manager構成のビルドに 成功した場合だけPRを作成して自動マージします。
| ワークフロー | 実行間隔 | 更新対象 |
|---|---|---|
update-flake-ai.yml |
毎日 | llm-agents、エージェントブラウザー、エージェントスキル |
update-flake-stable.yml |
3日ごと | nixpkgs、nix-darwin、home-manager、nix-index-database |
両ワークフローともcache.numtide.comを利用し、
homeConfigurations."nosuke@linux-x86_64".activationPackageを検証します。
更新はリポジトリへマージされるだけなので、各マシンではgit pull後に
必要な切り替えを実行します。Homebrewのbrew-src、nix-homebrew、tapは対象外で、
必要なときに手動で更新します。
dotfiles/
├── flake.nix
├── flake.lock
├── nix/
│ ├── hosts/
│ │ ├── darwin/
│ │ └── linux/
│ ├── nix-darwin/
│ │ ├── system.nix
│ │ ├── homebrew.nix
│ │ ├── homebrew-video.nix
│ │ ├── fonts.nix
│ │ ├── macos-defaults.nix
│ │ └── nix-cleanup.nix
│ └── home-manager/
│ ├── home/
│ ├── platforms/
│ ├── roles.nix
│ ├── presets/
│ ├── programs/
│ └── data/
├── .config/
│ └── nvim/
├── docs/
├── secrets/
├── tools/
│ └── dotbench/
└── .github/
└── workflows/