Skip to content

gapul/dotfiles

Repository files navigation

dotfiles

License: MIT

macOS 環境を Nix flake で declarative に管理(nix-darwin + home-manager + sops-nix)。

📖 日常コマンドは docs/CHEATSHEET.md を参照


Fork して使う場合

# 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

コマンド一覧

🟢 Justfile レシピ

以下は 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 のショート

🟥 コード品質 (git-hooks.nix + treefmt)

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.nixpreCommit.hooks を変更 → nix develop で再生成
  • .pre-commit-config.yaml生成物(store パス依存)。.gitignore 済・非追跡。fork 後は nix develop ./nix で生成
  • flake は nix/ サブディレクトリにあるため、treefmt フックは git ルートから root 検出に失敗する。整形フックは per-file の nixfmt-rfc-style を使い、treefmtnix 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

設計判断: /nix を復号化 + fstab から noauto 削除

Determinate Nix のデフォルト構成は:

  1. /nix ボリュームを FileVault 暗号化
  2. /etc/fstabnoauto を付与
  3. 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 マウント状態確認、fstabnoauto 戻ってたら 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 = mouseglobal:f18=...)でparse 中断。+show-config で適用状態確認、config の上から 1 行ずつ消して原因特定

About

Personal dotfiles management system

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors