UbuntuとDebianでNixを活用:複数バージョンの共存とアトミックなロールバック

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

依存関係の地獄からの脱却

APTのような標準ツールはシステムの安定性には優れています。しかし、3つの異なるバージョンのNode.jsを動かしたり、グローバルなファイルシステムを汚さずに新しいパッケージをテストしたりする場合には苦労します。4GB RAMのUbuntu 22.04 VPSで試したところ、Nixによってデプロイのオーバーヘッドが大幅に削減されました。マイナーなユーティリティのために、それぞれ300MBのRAMを消費する5つの独立したDockerコンテナを立ち上げる代わりに、現在はNixを介してネイティブかつ分離された環境で実行しています。

Nixがもたらすパラダイムシフト

なぜNixがDebianベースのシステムにとって根本的な転換となるのかを理解するには、Nixが普段使っているツールと比べてどのようにファイルを処理するかに注目する必要があります。

1. Nix vs. APT

APTはファイルを/usr/binのような共有ディレクトリにインストールします。これにより、単一のPythonライブラリをアップグレードすると、誤って他の3つのアプリケーションが壊れてしまうようなグローバルな環境が作成されます。Nixは、すべてのパッケージを/nix/store内の固有のサブディレクトリに保存することでこれを回避します。これらのディレクトリ名には、一意の暗号化ハッシュが含まれています。このため、Python 3.8、3.10、3.12を、互いの存在を関知させることなく同時にインストールできるのです。

2. Nix vs. Docker

Dockerはコンテナによる分離を提供しますが、これにはディスク容量と起動時間に大きな代償が伴います。基本的なUbuntuのDockerイメージは、ツールをインストールする前でも80MBほど消費します。Nixは、ネイティブバイナリのパフォーマンスを維持しつつ、パッケージレベルの分離を提供します。私は特定のC++コンパイラが必要な開発環境でNixを使用しています。2GBものイメージのオーバーヘッドなしに、コンテナのような再現性を得ることができます。

Nixを使用する現実

ワークフロー全体を移行する前に、実用的なメリットと学習曲線を比較検討する必要があります。

メリット

  • アトミックなアップグレード: Nixは更新中にファイルを上書きすることはありません。単に新しいシンボリックリンクを新しいバージョンに向けるだけです。アップデートに失敗しても、システムは以前の状態と全く同じまま保たれます。
  • sudo権限不要: 初回のセットアップが完了すれば、どのユーザーでもソフトウェアをインストールできます。これは、ルート権限はないが特定のバージョンのripgrepが必要な共有サーバーにおいて、非常に大きな利点となります。
  • ポータブルな環境: Gitリポジトリにshell.nixファイルを置くだけで、チームメイトがそれをクローンした際、コマンドを1つ実行するだけで、あなたが使用したのと全く同じツールチェーンを手に入れることができます。

トレードオフ

  • ディスク消費量: 分離は無料ではありません。Nixは依存関係の複数のバージョンを保持するため、数週間の実験後には/nixフォルダが簡単に20GBや30GBに膨れ上がることがあります。
  • 新しい言語: Nixエクスプレッション言語を学ぶ必要があります。これは関数型言語であり、標準的なBashやPythonスクリプトに慣れている人には異質に感じられるかもしれません。

UbuntuとDebianでのセットアップ

ほとんどの本番環境のセットアップには、マルチユーザーインストールをお勧めします。これにより、専用のnixbldグループと複数のビルドユーザーが作成されます。この構成はセキュリティを向上させ、各ユーザーのプロファイルをプライベートに保ちながら、複数のユーザーでNixストアを共有できるようにします。

まずストレージを確認してください。ルートパーティションに少なくとも15GBの空き容量があることを確認しましょう。容量が少ない場合は、インストールを開始する前に専用のSSDまたは別のボリュームを/nixにマウントしてください。

実装ガイド

1. インストール

公式のマルチユーザースクリプトは、現代的なDebian系システムにとって最も信頼できる方法です。必要なsystemdユニットを自動的に構成してくれます。

sh <(curl -L https://nixos.org/nix/install) --daemon

インストーラーが終了したら、Nixプロファイルを読み込んで環境変数を更新します:

. /etc/profile.d/nix.sh

2. パッケージの検索とインストール

Nixは、現在80,000以上のパッケージをホストしているnixpkgsという巨大なリポジトリから取得します。htopのような特定のツールを探すには、検索コマンドを使用します:

nix-env -qaP htop

システムファイルを変更せずに、ユーザープロファイルにパッケージをインストールするには:

nix-env -iA nixpkgs.htop

3. 即時のロールバック

変更を加えるたびに、新しい「ジェネレーション(世代)」が作成されます。ツールの新バージョンをインストールしてスクリプトが壊れた場合、すぐに履歴を確認できます:

nix-env --list-generations

以前の動作していた状態に戻るには、以下を実行するだけです:

nix-env --rollback

4. 一時的なツールのためのnix-shellの使用

これは間違いなく、開発者にとって最高の機能です。Python 3.11とrequestsライブラリを必要とする Pythonスクリプトを実行したいが、それらをシステムに永続的にインストールしたくない場合を想像してください。一時的なシェルに入ることができます:

nix-shell -p python311 python311Packages.requests

exitと入力した瞬間、それらのパッケージはPATHから消えます。システムはクリーンなまま保たれますが、その1つのタスクに必要なものはすべて手に入っていたのです。

システムを軽量に保つ

Nixは古いバージョンを自動的に削除しません。クリーンアップを行わないと、最終的にディスク容量が不足します。Nixストアがディスク使用率100%に達したために、サーバーが停止したケースを見たことがあります。

ガベージコレクション

どのアクティブなジェネレーションからも使用されていないパッケージを削除するには、以下を実行します:

nix-collect-garbage

より徹底的に、すべての古いジェネレーションを削除して(最大限の空き容量を確保して)クリーンアップするには:

nix-collect-garbage -d

最終的な戦略

APTと並行してNixを運用することは、Linux管理へのハイブリッドなアプローチを提供します。私はカーネル、SSH、systemdなどのシステム基盤にはAPTを使用しています。それ以外のCLIツールから複雑な開発ランタイムに至るまで、すべてにNixを使用しています。この分離により、ベースOSの安定性を維持しながら、アプリケーションに対して完全な柔軟性を持たせることができます。PPAの競合や壊れた依存関係に疲れているなら、Nixはワークフローの論理的な次のステップとなるでしょう。

Share: