🐿️

devboxを使った感想

2024/09/23に公開

この記事で書いていること

  • devboxの概要と感想

devboxとは

devboxはjetifyの環境作成ツールです。Nixを使います。
通常のホームパッケージマネージャとしても利用可能。[1]
このツールは、一言でいうと「Nixを環境構築ツールとして使いやすくしたラッパー」です。似たものとしてはFloxが出てるみたいです。
何が出来るかと言うと、例えば「PCにPythonとVimをグローバルにインストールしていないが、このプロジェクトフォルダの中だけではPythonとVimを使いたい」と言うようなニーズに応じたローカル環境の構築がワンツールで出来るようになります。また、対応したDockerfileなどを自動生成し、Dockerコンテナにも同様の環境を再現できるようになります。

Nixを使う利点

devboxを使う利点の多くは、ほぼNixを使う利点と等価という印象がした為、列挙します。

  • オーバーヘッド無し
  • ホスト環境とシームレスに繋がる「ゆるいisolated環境」を実現できる。例えば、ホスト環境の共有ライブラリを使うようなプロジェクトなどではそのまま利用可能
  • いつも使うホストに入れているシェルや開発ツールなどがそのまま活用可能
  • nvmなどの独自の言語やaptなどのOSごとにPMを換えて管理する必要がない
  • Linux/Mac環境では導入はそこまで難しくなく、管理者権限も不要
  • nixpkgsはエコシステムが充実しており、言語・ツールなんでもというくらいかなり広範囲にカバーされている
  • あらゆる生成物は全て/nix/store内で構築されるので、ホストのそれ以外の部分を歪めるリスクが少ない
  • 宣言型ファイルで簡単に環境を共有・再現可能
  • 謎のライセンス料等なし

バニラNixより良いと感じた点

実際のところ、このツールは極論、素のNixと出来ることは大差ありません
つまり、バニラNixや、せめてdevenvのようなツールに精通していて上手く扱えるなら、それに越したことはありません。[2]
が、以下のメリットがあるかと思います。

  • jsonのスキーマが使える。その中身も難しくはない
    • Nixは独自構文で補完も使いにくく、ドキュメントが散逸しすぎていてPMとは思えないほど学習コストが無駄に高い為大変
    • ただし、最終的にある程度のNixの理解は結局必須
    • 細かいチューニングをしたい場合は結局Flakeを作成することになるので、その手のことは必要
  • Dockerfiledevcontainer, Nixならお馴染みdirenvでの.envrc生成もお手軽
  • Nodeで言えばpackage.jsonと同じ感覚でscriptsを仕込みやすい
  • パッケージのバージョンインストールのタグ固定が難しくない
    • nixhubと強く連携しており、python@3.12.0などと書ける[3]
    • 素のNixではパッケージのバージョン指定はコミットハッシュのハードコードが必要な為、非常に設定ファイルからの見通しが悪い
  • 専用のVSCode拡張機能を使うと上手くVSCode内の諸々が連携されます
  • Process Composeが組み込みコマンドでサポート[4]

主な仕組み

ざっと見は以下のような形です。説明よりは使ってみたほうが分かるかもしれません。

  • ルートのdevbox.jsonをベースに.devboxフォルダにFlakeを生成する
  • ここで、必要なパッケージは存在しなければダウンロードされ、キャッシュがあれば使い回されるように設定される
  • 上記を軸にイミュータブルな読み取り専用パッケージを生成し、シンボリックリンクを貼る
  • 環境が更新される事に新しいビルドリンクが設定される。例えば、nix/profile/default-3-link
  • スクリプト類は全てPOSIX互換(いわゆるbash互換の.sh)で生成される
  • 全ては.devboxフォルダ内で行われており、その様子は確認できる

注意点

  • 2024年9月現在、正式リリースではありません(v0.13.0)
  • ホスト環境と緩い統合をしているメリットの反面、何かしらバッティングするような事象が発生する場合があります
  • NixなのでWindows環境には非対応です(ただし、WSLであれば使えます)
  • jetifyのサービスと紐づけられることが想定されたコマンドが幾つかあります: cache, secrets

インストールについて

公式マニュアルに記載があります。
私の場合は、nix-installer経由でNixを導入済みで、home-managerをベースにホーム環境を構築しているため、ここに書かれている記載方法ではなくホームマネージャのパッケージの一部としてインストールしました。

基本的な使用法

devboxを最初に使う際のみ、時間がややかかります(自分は3~5分くらいでした)。

devbox init # プロジェクト初期化
devbox add go@1.23.0 # パッケージの追加
devbox install # devbox.jsonで色々環境構築
devbox shell # 仮想環境に入る

devbox.json

とにかくシンプルなのが素晴らしい。
Goの開発環境を簡単にセットアップする例を以下に示します。

  • packagesは基本的にnixhubのパッケージ名を指定します。バージョン指定がある場合はfoo@1.0.0のように指定可能。github:xxxxxなどのようにしてFlakeの追加も可能
  • shellキーのinit_hookではdevbox shelldevbox run hogeで毎回発火して欲しいスクリプトを書きます
  • scriptsキーではdevbox run xxxxで起動して欲しいスクリプトを書きます
  • これらのスクリプト系はPOSIX互換のシェルスクリプト(要はbashなどで動く文法)で生成される為、その手の文法で書く必要があります
  • envで環境変数を定義できます。ここではGOPATHをルートのgoフォルダに引き込むことで、プロジェクトルートでパッケージの管理ができるように設定します
{
  "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
  "packages": ["go@1.23.0"],
  "shell": {
    "init_hook": [],
    "scripts": {
      "test": ["go test -v ./..."]
    }
  },
  "env": {
    "GOPATH": "$PWD/go",
    "PATH": "$GOPATH/bin:$PATH"
  }
}

コード生成機能

単純ですが、何気に良いと思った機能です。devbox initの際に一緒に叩くと良いかと思います。
Dockerコンテナへの移植もそうなんですが、Nixはdirenvを使った移動での環境スイッチングが非常にメジャーです。
何が出来るかというと、direnvツールさえ入れていれば、.envrcがあるフォルダに移動した瞬間環境をスイッチングできます。実際には専用のスクリプトが必要なのですが、それをサッと生成してくれるところは良いと思います。

devbox generate devcontainer
devbox generate dockerfile 
devbox generate direnv
devbox generate readme

依存キャッシュの削除

現段階のストアキャッシュの削除コマンド的なものは特にサポートしてないみたいです。なのでNixの機能で除去は行います。
以下は 公式ドキュメントの引用です。

devbox run -- nix store gc --extra-experimental-features nix-command

オプションの--extra-experimental-features nix-commandnixコマンドを例外的に有効にするという意味で、先述にあるような有効化をしていたら必要ないものです。
現状のNixは非常にヤヤコシイのですが、nix-collect-garbageというコマンドもあり、こちらも同等の機能を持っています。
基本的に.devboxフォルダの中身は放置で構わないと思いますが、.devboxフォルダをキレイにしたい場合は1回フォルダごと消してしまって、devbox installすると再構築されます。

おわりに

体験としては結構良かったです。
感覚としては、実際には「Makeに対するCMakeみたいなヤツのNix版」という印象を持ちました。
私の場合LinuxにてNixは「便利なホームパッケージマネージャ」としての恩恵を享受しているものの、Nixそのものは非常にとっつきづらいと思っており(つらい)、「正直これでの環境構築はあまりにもシンドい」という印象で、あまり活用は出来てません。
が、これはスキーマ付きJSONとコード生成で一番やりづらい所をシンプルにカバーしてくれるので結構良いと思いました。

恐らくDockerfileを使ってアレコレするまでもなかったり、ホスト環境を使って何かやる必要がある簡易なバッチプログラムの環境構築なんかには迅速にローカル環境が立ち上げられて、結構使えそうだと思います。

脚注
  1. 個人的には郷に習えでglobalを使うのは忌避感があるかな、と思います。Nixのホーム環境自体はHome Manager使うのが良いかな、って思います。 ↩︎

  2. これが私にはとっても難しいんです…笑 ↩︎

  3. nixpkgsのコミットハッシュをインデックスしているjetifyのサイト ↩︎

  4. 個人的にはこの機能を使う粒度はもうDockerに展開しちゃった方が利が大きくなりそうかなって思います、、 ↩︎

Discussion