開発マシンの環境セットアップをAnsibleからNixに移行した
Table of Contents
有給消化期間中に前から気になっていたNixを使い始めたはなし。

Ansibleによるセットアップ #
以前はAnsibleを使ってMacbookをセットアップしていた。 正直特に不満はなく、足りない部分は自分でモジュールを書いたりして便利に使っていた1。
不満点があるとすれば、Ansibleのplaybookを管理しているgitリポジトリをprivateにしていたこと。 ssh用の秘密鍵やGitHubのtokenなど、秘密情報はAnsible Vaultで暗号化して保存していた。 暗号化しているとはいえ秘密情報は秘密情報なので、publicにする気にはならなかった。 privateなので、当然playbookを直接共有することができず、不便を感じていた。 ただ、これは秘密情報をどう扱うかという構成に関する不満であって、Ansibleに対する不満ではないのはお察しの通り
Nixに移行した理由 #
秘密情報の管理については、以下の記事を参考に一昨年頃から1Passwordを参照する方法に置き換えていった。

この方法なら、git管理下のファイルには1Password上のIDのみを書けばよく、暗号化したものを含めて直接書く必要はなくなる。 つまりgitリポジトリを丸ごと公開しても問題がないということになる。
とはいえ、すでにAnsible Vaultとして暗号化したファイルのコミットログがあるリポジトリをそのまま公開するわけにはいかない。 どうせリポジトリを作り直すなら別の管理方法にしてみるかと思い立ったのが去年の秋頃2。
当時自分の観測範囲内にちらほら登場するようになったNixが気になっていたのと、 ちょうど同じタイミングでNix meetup #1が開催されることを知り、これに参加したというのが決め手になった。
Nixへの移行 #
NixとNixOSの違いもわからない状態から始めたので、まともに使えるようになるまで時間がかかった。 リポジトリは以下にある。
Nixの設定にはnix langという言語を使う。 nix langは動的型付けな関数型言語(らしい)。 nixでインストールできるパッケージのインストール設定もすべてnix langで書かれており、再現性が高い(らしい)。
特に特徴的なのは、異なるバージョン(ソフトウェアのバージョンだけでなく、ビルドオプションなども含む)のパッケージはすべて異なるものとしてインストールされること。
/nix/store
以下に、パッケージ依存ツリーに含まれるパッケージのすべてのバージョンが保存されている。
例えば、手元の環境では openssl-3.3.2
だけで6種類のバージョンが存在する。
❯ ls /nix/store/ | rg 'openssl-3.3.2$'
1a4j0c5xn6xl53z77sifkncg3fing1qj-openssl-3.3.2
8ms7abrwg2nbqdjdcdf1aig4y7yha4v7-openssl-3.3.2
hfn95nq7wr6sidn5vridlk1a4drira0r-openssl-3.3.2
hx7ksp6xyw385k3wlvng15sd4s15vr0i-openssl-3.3.2
qm16x7kk34j7b6h90dfpj30fjazsswpv-openssl-3.3.2
rm2ss9qyvxad4q9iwdqanil25pj1rqwv-openssl-3.3.2
これにより、依存対象の非互換によりパッケージのインストール及び動作に支障が出ることがない、というのがウリらしい。
パッケージのインストールやファイル類の配置はhome-managerで、 Mac固有の設定はnix-darwinで行うのが一般的なようだ。 nix-darwinからはHomebrewのパッケージをインストールすることができるので、必要なものはほぼ間違いなく網羅できる。
もともとAnsibleで環境をセットアップしていたので、そこからmigrate的なことをする手もあるにはあったが、 今回は勉強のためにも一から少しずつセットアップしていった。
公式のドキュメント、および先人の記事に大変の世話になった。 以下に参考にさせていただいた資料のURLを挙げる:
- First steps — nix.dev documentation
- Home Manager Manual
- 入門Nix - Zenn
- 📦 Nixでlinuxとmacの環境を管理してみる | Happy developing
- nixのコマンドを解説してみる #NixOS - Qiita
- Nixでdotfiles管理できるようになるまでのメモ - Zenn
- Mac用 Nix、nix-darwin、home-manager セットアップ完全手順 (2024年6月改訂版) #nix - Qiita
Nixに移行してよかったこと #
移行してよかったことを挙げてみる。
設定対象範囲が広い #
まずはパッケージの種類が豊富なところ。 必要なものはたいていパッケージ化されている。 パッケージの総数、及びメンテナンスされているパッケージ数は、他のパッケージ管理ツールと比べて群を抜いて多いらしい。

パッケージマネージャごとの、パッケージ数(横軸)と更新されているパッケージ数(縦軸)のグラフ
Mac固有の設定を扱う nx-darwin
は、defaultsの変更も宣言的に行うことができる。
たとえば、キーリピート速度の変更やDockの表示位置変更など、設定アプリから変更する内容はたいてい記述することができる3。
新しいMacをセットアップする際に、毎回ポチポチと設定変更していたものが nix-darwin switch
コマンド一発で設定できるのは非常に楽。
Language Serverの対応 #
nix lang用のLanguage Serverが提供されているのも便利。 現在はnixdとnilがよく使われているようだ。
VSCodeであればNix IDEを、 Zedならnix language supportを入れれば手軽に利用することができる。
syntax checkはもちろん、インストールされるパッケージのバージョンまで表示されるのが面白いところ。

依存解決 #
Nix特有の、パッケージの依存が壊れないというメリットももちろんあるが、壊れないということは何もおこらないということなので、直接的に恩恵を感じにくい。 もちろん、平和なのはいいことである。
Nixに移行するときに苦労したこと #
Nixにしてよかったことばかりではなく、不便に感じている点もある。 ただし、これらはまだNixとの付き合い方に慣れていないことから生じている可能性も大いにある。
気軽に設定ファイルを弄りにくい #
Nixで配置したファイルは、全て /nix/store
以下へのsymlinkとなる。
❯ ls -l ~/.config/git
total 0
lrwxr-xr-x@ 1 nagata-hiroaki staff 81 Feb 11 08:01 config -> /nix/store/4ynh4s1g5c97as5n979lmi52n9xx56df-home-manager-files/.config/git/config
lrwxr-xr-x@ 1 nagata-hiroaki staff 81 Feb 11 08:01 ignore -> /nix/store/4ynh4s1g5c97as5n979lmi52n9xx56df-home-manager-files/.config/git/ignore
また、 /nix/store
以下のファイルは全てreadonlyとなっている。
❯ ls -l /nix/store/ | head -5
total 456752
-r--r--r--@ 2 root nixbld 3206 Jan 1 1970 001gk5gmc1yyj4anm2cbndlw1l427kjj-requests-2.32.3.tar.gz.drv
-r--r--r--@ 2 root nixbld 3187 Jan 1 1970 0021g3y6nccaf9qm7sic3h3jq6i3scq7-lcms2-2.16.tar.gz.drv
-r--r--r--@ 2 root nixbld 3743 Jan 1 1970 003zs7gd0zaprnpvfdg2ix6m20fqi4x1-source.drv
-r--r--r--@ 2 root nixbld 5105 Jan 1 1970 004527k24fxsaillq3bfrij80m6qqgv9-python3.12-pytest-7.4.4.drv
不用意な変更が入らないので構成が壊れないという利点はあるのだが、
試行錯誤中の設定ファイルなどはこれでは不便。
ちょっと設定をいじるたびに毎回 nix-darwin switch
するのは効率が悪い。
/nix/store
にバージョンごとにコピーしてsymlink、というのはNixの基本方針でもあるので、これを回避するのは難しそう。
仕方がないので変更が多いファイルについてはNixでは配置せず、適宜リポジトリ管理下のファイルに内容をコピーすることにしている4。
デスクトップアプリがアプリケーション一覧に表示されない #
これは昔からある問題のようだ。
例えば programs.vscode.enable = true;
とするとVisual Studio Codeがインストールされるのだが、
これが /Applications
あるいは ~/Applications
にsymlinkされないのが原因のようだ。
❯ ls -l /nix/store/mdlr8182am37p84y5nf57wgrn18wgqja-vscode-1.94.2/Applications/
total 0
dr-xr-xr-x@ 3 root wheel 96 Jan 1 1970 Visual Studio Code.app
アプリケーション一覧に表示されないということは、Alfredからのアプリケーション起動もできないということなので困ってしまう5。
上記のissueではあれやこれやして Applications
ディレクトリにsymlinkする方法が議論されているが、
面倒なのでデスクトップアプリは nix-darwin
経由の Homebrew
インストールしてしまっている。
Homebrew
によるインストールであれば /Applications
にsymlinkされるので、アプリケーション一覧にも問題なく表示される。
/nix/store
以下が肥大化する #
Nixでインストールしたパッケージは、依存関係にあるものはバージョン違いのものも全て /nix/store
に保存される。
これにより依存に関する問題を回避しているわけだが、複数バージョンのパッケージが同時にインストールされている状態になるため、当然 /nix/store
以下が肥大化する。
手元の環境では /nix/store
が 13GB になっていた。
❯ du -sh /nix/store
13G /nix/store
ちなみに、数年使っているHomebrew管理の /opt/homebrew
は 12G だった。
❯ du -sh /opt/homebrew
12G /opt/homebrew
適当なタイミングで nix store gc
することで不要になったパッケージを削除することはできる。
これから #
先日、転職に伴う支給PCのセットアップがあり、その際に今回整備したNixによる環境セットアップをまっさらなMacbook上で実施する機会6があった。 一発ではうまくいかなかったものの、それを受けての修正もできたので、十分実用できる段階に持ってこれていると思う。
できればCodespacesのセットアップもNixで行いたいところだが、 現職ではCodespacesの出番がないのでモチベーションが低い・・・。
CPUのアーキテクチャとか、ホームディレクトリのパスとか、 マシンごとに固有の設定をしたい場合にどうやるのかがまだわかっていないので、そのあたりは改善の余地がある。
NixOSを触ってみたい気持ちもあるのが、触ってみる以外の用途があるかというと、あるかなぁ。
おわりに #
環境セットアップの手段をAnsibleからNixに移行して、今のところは満足している。 固めの設定ができていることを実感できるし、何より新しいツールを触るのは楽しい7。
Nix meetup #2もあるようなので、都合をつけて参加したいところだが・・・行けるかな?
-
ghqでリポジトリをcloneしてくるモジュールや、 homebrew-gomodするモジュールなど。 簡単なPythonのコードを書けばいいだけなので、気軽に追加できる。 ↩︎
-
1Password管理にしてから1年ほど経っているわけだが、その間新しいPCをセットアップする機会がなく、やる気が出なかったのである。 M1 Macbookが快適すぎるのがいけない。 ↩︎
-
例えばこのあたり https://github.com/handlename/dotfiles/blob/d57731a1bd4aa9e13ab865d77c4dccaa3bc00205/darwin.nix#L17-L48 ↩︎
-
現状ではZedの設定ファイルがそれにあたる。 リポジトリ管理下にはあるが、moduleをimportする部分はコメントアウトしている。 ↩︎
-
実際にはエディタやブラウザなど、常用するアプリケーションの起動・切り替えにはBetter Touch Toolによるキーバインドを設定しているので、 それらを使う分には問題はなかったりする。 とはいえそうではないアプリケーションもインストールしたいので、アプリケーション一覧に表示されないのはやはり困る。 ↩︎
-
実はPC納品タイミングの関係で、最初の1週間は仮の支給PCを使っていた。 つまり1週間で2回、まっさらなMacbookをセットアップする羽目になったのだが、おかげで十分にテストをすることができた。 ↩︎