🏡

ぼくんちのにっくす

に公開

はじめに

エンジニアっぽいことをしていると、仕事のためにいろいろツールを使いたくなるときがあります。
例えば私の場合、ターミナルでテキスト編集、VM操作、AI実行をCLIでしたり、時には最低限webブラウザがGUIで必要だったりします。

これらのツールを使うには基本的に何らかの方法でインストールが必要になります。
ですがツールが多くなってくると、インストールの管理が大変になってきます。

私は兼ねてより、my dotfiles(dotfilesについてはこちら)をgit管理しています。
ここで、日常的に使用するツールは全てインストールできるようにソースを管理していました。

しかし初回だけ絶妙な手動設定が必要で、次に同じことをする頃にはもう忘れているようなものでした。
スクリプト作るのも面倒だし、もっとスマートに管理できないかなと思っていました。

そんななか、Nixに本格的に移行してみることにしました。
今まではNixについてきいたことはあったものの本格的に使うところまではいっておらず、devboxのようなラッパーツールを使っていました。
今回はNixで自己マシン環境を管理してみた感想などをまとめてみたいと思います。

Nixって?

Nixとは公式によると、純粋関数型パッケージマネージャ(purely functional package manager)とのことです。
何だか難しそうな言葉ですが、一言でいうと「同じ入力からは、必ず同じ出力ができるという性質でパッケージを作る」ことから、このような名前がついていると理解しています。

普通のパッケージマネージャが、環境を直接変更または上書きして状態を変化させて管理するのに対し、Nixは依存関係・バージョン・ビルド手順といった入力情報から成果物を計算し、その結果を新しい場所に(同じ結果になるように)保存します。

観点 Nix その他のパッケージ管理
考え方 入力から成果物を“計算”する システムを書き換える
出力の安定性 入力が同じなら必ず同じ 環境状態に依存
保存場所 /nix/store にハッシュ付きで別保存 共有ディレクトリに上書き
バージョン共存 可能 可能なものもある
ロールバック 簡単に可能 可能なものもある
再現性 完全に同じ だいたい同じ

aquaやmiseなどのパッケージマネージャでもバージョン共存やロールバックは可能ではありますが
Nixと比較すると、Nixの特徴は再現性の高さにあると言えると思います。

Nixについては、たいへんわかりやすい詳しい説明がこちらにあるので、興味のある方はぜひ読んでみてください。

「Nix」と呼ばれるものたち

「Nix」と呼ばれるものが大きく3つあり、混乱しないように整理しておきたいと思います。
以下の異なるものを指すことがあります。

  1. Nix

    • パッケージ管理の仕組み
    • イメージとしてはパッケージマネージャ本体
  2. Nixpkgs

    • Nix用の巨大なパッケージ定義、レジストリ
    • 12万もの(2026年2月時点)パッケージが管理されているおり、ここからパッケージを選んでインストールすることができる
  3. NixOS

    • Nixを中心に設計されたLinuxディストリビューション
    • OS全体をNixを使って宣言的に管理

Nixでできることの例

なんとなくNixのイメージがつかめたところで、実際にNixを使うとどんなことができるのか、例を挙げてみたいと思います。

  1. 開発環境を一発で再現できる

    • 言語・ツール・ライブラリなどをまとめて定義しておけば、コマンド一発で整う。
    • 新しいPCでも同じ環境が再現可能。(同じ設定なら時間経過によって結果が変わることがない)
    • 個人専用の環境、特定プロジェクト共有用の環境、どちらにも使える。
  2. 一時的なクリーン環境を作れる

    • 特定のツールを試したいときなど、環境を汚さずに一時的な環境を作れる。
    • インストール不要で即利用、終了すれば消える。
  3. CI/CDにも使える

    • CI/CD環境もローカルと同じ設定で構築すれば、「ローカルでは動いた」が起きにくい。
  4. ロールバックできる

    • もしアップデートして依存関係が壊れてしまっても履歴から戻せる。

したかったこと

以上のように、Nixは環境構築のユースケースに応じて様々なことができます。
特に私がやりたかったことは以下のようなものでした。

  1. 異なるPCで同じ開発環境をコマンド一発で再現したい。
  2. dotfilesのシンボリックリンクなど、初回セットアップの手動作業をなくしたい。

つまり、個人環境を「手順」ではなく「コード」で管理したいというのが目的でした。
通常のパッケージマネージャでいうところのグローバルインストールのようなイメージで、個人マシンの環境をNixで管理したいと考えていました。
マシンはmacOSを想定しています。

やったこと

home-managernix-darwinを使用してパッケージと設定周りを管理しました。

  1. 個人環境パッケージ管理

    NixPkgsからほぼすべてのパッケージをインストールすることで、環境構築の再現性を高めました。
    NixPkgsにないパッケージについてはnix-darwinのhomebrew管理を利用して管理するようにしました。

  2. dotfiles のNix管理

.zshrc、.configなどのリンク設定を管理するようにしました。
以前はgit管理している設定ファイルをln -sで手動でシンボリックリンクを作成していましたが、home-managerでパッケージのインストールと同時に設定も反映されるようにしました。

下記が今回nixで構築したディレクトリ全体イメージです。
nix

移行した感想

当初の目的を満たせたのと、個人的にも運用面は満足しています。

とにかく環境の再現が楽になったのが大きなメリットでした。
今まではmiseとhomebrewを併用して管理していましたが、Nixをインストールしてコマンドを実行するだけで、同じ環境が再現できるようになりました。
例えば、home-managerの場合は下記です。

nix run home-manager/master -- switch --flake github:r-3110/dotfiles#<output>

リモートのflakeを直接実行して環境構築することができます。(※必ず信頼できるflakeのみを指定するようにしてください。)
ロールバックも可能なので壊れてもすぐに復旧できる安心感もあります。

デメリットは正直そこまで感じていませんが、強いてあげるとすればまだNixのコードに慣れていないことですかね。
ただ、正直今はAIに書かせるで全然問題ないと思っているのであまり気にしていません。
コードは読んで慣れていけばいやでもわかるようになります。

デメリットではありませんが、注意点としては以下のようなものがあると思います。

  1. 基本的にパッケージ全体の更新になるため、特定のパッケージだけを更新する(aws-cliだけあげたいなど)のは特別に工夫が必要

    • 基本はflake updateでパッケージ全体を更新することになる
    • NixPkgsはレジストリ全体がgit管理されているようなものでflake updateは実行時点の最新コミットを取得してくるイメージ
    • つまりflake updateだと、ver全更新のため時間が掛かる
  2. Nixで構築・設定した結果物は基本read onlyである

    • 一応、symlinkなどはread onlyでなくすることもできる
  3. すべてのパッケージがNixPkgsにあるわけではない

    • これはNixPkgsに限らずだが、新しいものやマイナーめなものはflakeで自分で管理する定義を作るか他のパッケージも併用する必要がある

しかし1、2についてはNixの設計思想に根ざした、再現性、一貫性に沿ったものであり、むしろNixの強みといえる部分と考えられます。
そのため、これらの点は理解した上で運用していく必要があると思いました。

まとめ

Nixは学習コストが高いものの、環境構築の再現性や管理のしやすさなど、多くのメリットがあります。
まだまだ使いこなせていない部分も多いですが、個人的にはニーズにマッチしているので今後も使い続けていきたいと思っています。
今後は、macOSの設定、Agent関係のスキルやmcpなどもNixで管理してみたいなと思っています。

以上、Nixを使って開発環境を管理してみた感想でした。
興味湧いた方もよかっら試してみてください。

NCDC テックブログ

Discussion