macOS 環境を Nix flake で declarative に管理(nix-darwin + home-manager + sops-nix)。
📖 日常コマンドは docs/CHEATSHEET.md を参照
# 1. Fork ボタン → 自分の repo 名で clone
git clone git@github.com:<yourname>/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 2. nix/user.nix を編集(これだけで全 nix モジュールに反映)
$EDITOR nix/user.nix
# {
# username = "<your-macos-username>";
# gitUser = "<your-github-username>";
# gitEmail = "<your-email>";
# dotfilesRepo = "https://github.com/<yourname>/dotfiles.git";
# }
# 3. age 鍵を生成して .sops.yaml の public key を差し替え
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
# 出力された "# public key: age1..." の行を .sops.yaml の age1... に貼り換え
$EDITOR .sops.yaml
# 4. 元の所有者の secrets は復号できないので削除して空から始める
rm secrets/secrets.yaml
# 必要な secret を追加していく(例)
sops secrets/secrets.yaml
# (sops が新しいエディタ画面を開く → 自分の secret を YAML で記述 → 保存)
# 5. 個人 brew tap を整理(任意)
$EDITOR nix/hosts/darwin.nix
# - "gapul/openutau", "gapul/zrythm" は 作者個人の fork → 削除可
# - 不要な GUI cask も削っていい(brave-browser, gimp, blender 等)
# 6. bootstrap 実行
bash scripts/bootstrap.shクローン後にエディタで nix/user.nix, .sops.yaml, nix/hosts/darwin.nix を編集すれば、他は触らずに動く設計。
nix/
├── flake.nix # entry point (darwin/nixos/home-manager 各構成 + devShell)
├── user.nix # ユーザー名・メール等 (最初に書き換える)
├── hosts/ # マシン別: darwin.nix (メイン Mac) / macmini.nix / nixos-laptop.nix
├── home/ # home-manager: common.nix + OS 別 (darwin/linux/wsl/hyprland) + backup 系
├── lib/ # テーマ (palettes.json を SSO とする rose-pine dark/light)
└── pkgs/ # 自前パッケージ
configs/ # 各アプリの実 config (ghostty/zellij/aerospace/sketchybar/nvim/karabiner/yazi/...)
secrets/secrets.yaml # SOPS で age 暗号化
.sops.yaml # 受信者 (age pubkey)
scripts/bootstrap.sh # 新 Mac 用 0 → 1 セットアップ (Linux/WSL 版もあり)
windows/ # Windows 側セットアップ (winget/scoop/AutoHotkey/...)
templates/ # direnv 用 dev shell テンプレ (node/python/rust)
Justfile # 普段使うコマンド集
新しい Mac:
curl -fsSL https://raw.githubusercontent.com/gapul/dotfiles/main/scripts/bootstrap.sh | bash以下は just --list から自動生成(レシピを変えたら just docs で再生成)。
default # デフォルト: タスク一覧 (定義順で表示)
[Windows]
win-autostart-glazewm *flags # `*flags` で `-Unregister` (タスク削除) を渡せる
win-bootstrap *flags # Windows ネイティブの bootstrap を実行 (`just win-bootstrap` / `just win-bootstrap -DryRun`)
win-fmt # Windows 関連 .ps1 を PSScriptAnalyzer で lint (Warning 以上で exit 1)
win-fonts *flags # `*flags` で `-DryRun` `-Force` (既存も上書き) を渡せる
win-keymap *flags # `*flags` で `-DryRun` `-Clear` (Scancode Map 削除して standard に戻す) を渡せる
win-locale *flags # `*flags` で `-DryRun` `-SkipLanguageList` `-SkipSystemLocale` `-SkipHomeLocation` を渡せる
win-privacy *flags # `*flags` で `-DryRun` `-SkipWinUtil` `-SkipWin11Debloat` を渡せる
win-scoop *flags # `*flags` で `-DryRun` `-SkipBuckets` `-SkipApps` を渡せる
win-status *flags # apps.json (宣言) と winget list (実 install) の差分。MISSING があれば exit 1
win-theme *flags # `*flags` で `-DryRun` `-ActivePalette rose-pine-dawn` 等を渡せる
win-upgrade # winget 経由で入れた全 app をアップグレード (--silent --accept-*)
win-verify *flags # winget/apps.json の全 PackageIdentifier 実在検証 (`just win-verify` / `just win-verify -Strict`)
[secrets]
secrets cmd="edit" # sops 暗号化 secrets (`just secrets` = 編集, `just secrets rekey` = 全 recipient 再暗号化)
[サービス]
restart what="bar" # メニューバー/WM 系を再起動 (`just restart`=バー周り / 個別: sketchybar|borders|aerospace / all=全部)
[セットアップ]
dev what="" # devShell (`just dev`=入室[shellcheck/statix 使用可] / `just dev install`=hook導入のみ[非対話])
docs # README の自動生成部を `just --list` から再生成
obsidian-snapshot # Obsidian 設定を public dotfiles へ片方向スナップショット (追跡専用・vault→dotfiles)
ssh host # remote-env を別ホストで使う
[テーマ]
theme name="" # 全環境を palettes.json の現 active で render (`just theme rose-pine-dawn` で active 切替も可)
[バックアップ]
archive path # 例: `just archive ~/Downloads/old-project`
archive-find pattern # 例: `just archive-find "*.psd"` / `just archive-find old-project`
archive-ls # アーカイブ (--tag archive) の snapshot 一覧 (ID / 日付 / 元パス)
archive-stats # アーカイブの総容量・ファイル数
backup # warm バックアップを今すぐ実行 (launchd を kickstart) → ログ追尾 (Ctrl-C で追尾終了・backupは継続)
backup-check # リポジトリ整合性検証 (restic check)
backup-ls # 全スナップショット一覧 (Tags 列で warm / archive を区別)
gdrive cmd="status" # 共有用 ~/Cloud/GoogleDrive マウント操作。`just gdrive`=状態 / `remount`=再マウント / `open`=Finderで開く
restore snapshot dest="/" # `just restore a81c9de1 ~/Restore` 指定先へ (構造を保って展開) [alias: unarchive]
[掃除]
gc # 全レイヤー一括 GC (nix store + brew + pnpm + uv + ~/.Trash 等)
gc-deep # 重い再生成可能ディレクトリを削除 (30日以上更新の無い node_modules / rust target のみ。要再 install)
[構築]
gen action="" a="" b="" # システム世代の一覧/差分 (`just gen` = 一覧, `just gen diff [a] [b]` = 世代間パッケージ差分。sudo 不要)
rebuild # システム + ユーザー再構築 (Mac/WSL/Win 自動判別、普段使い)
rollback gen="" # 世代をロールバック (引数なし=直前へ, `just rollback 8` で世代番号指定。sudo)
update *inputs # flake input 更新 → rebuild (引数なし=全 input, `just update nixpkgs` で個別更新)
upgrade # 全レイヤーアップグレード (Mac/WSL/Win 自動判別)
[確認]
check what="" # 型チェック / 差分表示 (`just check` = 構文型チェック, `just check diff` = 差分ビルド)
doctor # 環境ヘルスチェック (Determinate upgrade 後などに走らせる)
fmt # コード整形 + lint を全追跡ファイルに実行 (OS 自動判別: Mac/Linux=pre-commit, Win=PSScriptAnalyzer)
outdated # 更新可能なものを一覧 (upgrade 前のプレビュー。brew + mas + flake inputs。非破壊)
search query scope="" # パッケージ検索 (`just search <q>` = brew+nixpkgs, `just search <q> all` = + cargo)
| コマンド | 説明 |
|---|---|
nh search <name> |
nixpkgs から package 検索(例: nh search firefox) |
| コマンド | 説明 |
|---|---|
nssh user@host |
rootless Nix(nix-portable)で nvim/yazi/zellij(自分の設定) |
just ssh <host> |
nssh のショート |
pre-commit フック・フォーマッタは nix/flake.nix で 宣言的に管理(git-hooks.nix / treefmt-nix)。
| コマンド | 説明 |
|---|---|
nix fmt |
nix(nixfmt) + shell(shfmt) を整形。nix/ 配下で実行 |
nix develop ./nix |
devShell 入室。.pre-commit-config.yaml を生成し .git/hooks に導入 |
nix flake check ./nix |
checks.pre-commit で nix/ を検査(CI と同じ) |
nix develop ./nix -c pre-commit run --all-files |
リポ全体にフックを実行 |
nix develop ./nix -c shellcheck scripts/*.sh |
シェルの手動チェック(任意) |
nix run nixpkgs#statix -- check nix |
nix lint(手動。enforced 外) |
commit 時に自動実行されるフック(.git/hooks/pre-commit):
| フック | 対象 | 内容 |
|---|---|---|
nixfmt-rfc-style |
*.nix |
整形チェック(未整形なら fail) |
deadnix |
*.nix |
未使用コード検出(モジュール引数 { lib, ... } は許容) |
shellcheck |
shell 全般 | lint(sketchybar 設定群と .envrc は除外) |
gitleaks |
全 staged | 機密 leak 検出 |
メモ:
- フックを編集するには
nix/flake.nixのpreCommit.hooksを変更 →nix developで再生成 .pre-commit-config.yamlは 生成物(store パス依存)。.gitignore済・非追跡。fork 後はnix develop ./nixで生成- flake は
nix/サブディレクトリにあるため、treefmtフックは git ルートから root 検出に失敗する。整形フックは per-file のnixfmt-rfc-styleを使い、treefmtはnix fmt専用 shellcheckは enforced 済。除外中の sketchybar 設定群はnix develop ./nix -c shellcheck configs/wm/sketchybar/...で手動チェック可- CI(
.github/workflows/check.yml)のpre-commitジョブがリポ全体で同じフックを実行
| コマンド | 説明 |
|---|---|
just doctor |
環境ヘルスチェック(/nix マウント・Login Items・fstab 状態) |
sudo /usr/local/bin/determinate-nixd init |
macOS update 後 /nix が見えない時 |
sudo /usr/local/bin/determinate-nixd upgrade |
Determinate Nix runtime 本体を更新(数ヶ月に1回) |
nh darwin switch |
システムだけ rebuild(just rebuild の半分) |
nh home switch |
ユーザーだけ rebuild |
nh clean all |
古い世代を一括削除 |
- Nix runtime: Determinate Nix(
nix.enable = falseで共存) - nix-darwin と home-manager は分離: #1462 (USER check bug)回避のため
- configs 編集 →
git add忘れずに: Nix flake は git-tracked しか見ない - 動的設定 (nvim/karabiner) は
mkOutOfStoreSymlink: GUI/CLI の書き戻しが dotfiles に反映 - secrets は SOPS-nix で復号:
~/.config/sops/age/keys.txtが必要。Bitwarden に backup 推奨 - direnv:
templates/<stack>/をプロジェクトにコピーしてdirenv allowで言語別 dev shell
Determinate Nix のデフォルト構成は:
/nixボリュームを FileVault 暗号化/etc/fstabにnoautoを付与- launchd デーモン
org.nixos.darwin-storeで遅延マウント
この設計は launchd daemon ベースの起動(nix-darwin の PR #1052 で wait4path 自動付与)を前提にしているが、Login Items / GUI 自動復元 / restoring Terminal は wait4path 範囲外。Ghostty・AeroSpace・sketchybar を Login Items で常駐させてる構成では、boot 直後に /nix がまだマウントされず config 読み込み失敗する。
deep-research によると、これはコミュニティで何年も解決してない有名な問題。 lilyball は login shell を C wrapper で包んでる、astratagem は「Nix で yabai 入れるのやめた」と発言してる。
対処 (現状の構成):
/nixボリュームをdiskutil apfs decryptVolume "Nix Store"で復号化/etc/fstabからnoautoを削除 → macOS のautomountdが起動序盤にマウント- Login Items が起動するときには /nix は既にマウント済 → config 読める
トレードオフ:
- ✅ Login Items 問題が完全解決
- ✅
wait4path経路で漏れる GUI / 復元 Terminal も解決 ⚠️ Determinate 公式サポート外設定(upgrade で fstab 書き戻される可能性 → bootstrap.sh で自動修正)⚠️ ボリューム暗号化が外れる- 実害は無い(/nix の中身は nixpkgs 公開バイナリ、Mac 本体は FileVault でカバー済)
自動修復: bootstrap.sh が新規 install 時に自動で復号化 + noauto 削除する。just doctor で日常チェック可能。Determinate upgrade 後はとくに just doctor 推奨。
| 症状 | 対処 |
|---|---|
| 再起動後に sketchybar / Ghostty / launcher が config 読まない | just doctor で /nix マウント状態確認、fstab に noauto 戻ってたら sudo sed -i '' 's/,noauto//' /etc/fstab |
/nix が見えない / shell でエラー |
sudo determinate-nixd init または sudo diskutil mount "Nix Store" |
nh: more values required |
新ターミナル開き直す(__HM_SESS_VARS_SOURCED の継承で env が古い) |
git push できない |
dotfiles の remote が SSH 化済 → ~/.ssh/config 確認 |
| pre-commit hook で commit blocked | leak は redact 表示、嘘陽性なら .gitleaks.toml の allowlist 追記 |
darwin-rebuild switch で USER エラー |
nix-darwin#1462 の bug。just rebuild(nh)で回避 |
Ghostty config の一部設定が無視される(quick-terminal-position 等が default のまま) |
Ghostty 1.3.1 は invalid な行(例: quick-terminal-screen = mouse、global:f18=...)でparse 中断。+show-config で適用状態確認、config の上から 1 行ずつ消して原因特定 |