VPSで開発環境を構築する方法を調べている時にnix-portableでdevShellをbundleできることを発見したので試してみた。 この方法を使うと開発環境を単一バイナリにできる。
概要
nix bundleを用いて開発環境を提供するderivationを単一バイナリにbundleする。 mkShellはderivationを提供しないため、devshellの定義にはnumtide/devshellを使用する。
やり方
numtide/devshellを使用してdevShellを定義したflakeを用意する。この時、packagesにpkgs.nixを含めること。nix bundle --bundler github:DavHau/nix-portable -o devshell .#devShells.{system}.defaultでbundleする。{system}の箇所はx86_64-linuxなど、ターゲットのアーキテクチャに合わせる。
./devshell/bin/devshellに実行ファイルが作成される。これを実行すると開発環境に入れる。
詳細はサンプルを参照して欲しい。
仕組みの説明
NixにはDerivationを単一バイナリにbundleするnix bundleというコマンドがあって、このコマンドを使用すると任意のDerivationを単一バイナリにできる。 また、nix bundleはbundlerを指定することで任意の方法でbundleすることが可能。
nix-portableはこのbundlerを提供することで、devShellをDerivationと見なし単一バイナリへと変換できる。
nix bundleについては過去に記事を書いたので、そちらも参照して欲しい。
これが役に立つ場面
インストールできるOSに制限のあるVPSとかで、環境をきれいに保ちつつNixで構築した環境を使う場面とかで役に立ちそうだと思った。 単一バイナリなのでDockerより手軽に環境を他者に投げられるので、環境の共有という面でも役に立ちそう。
問題点
- 開発環境に含めるツールが多いほどバンドルサイズが増加する。
- 自作したサンプルは350MBほどだった。
- bundlerに
github:DavHau/nix-portable#zstd-maxを使用すると圧縮にzstdを使用することもできる。この場合は277MBだった。初回起動に数秒かかるけど、サイズ削れるのでこっちの方が良いのかもしれない。
- devShellの作成に
numtide/devshellを使用する必要があるため、既存の開発環境から移行するのにコストがかかる。 - service-flakesのような高級なserviceを作成するモジュールが使用できない。
- 一応
numtide/devshellにもserviceを実行する機能はあるが、ただ複数コマンドをwrapするだけなのでservice-flakeと比較して貧弱。