• nix-portableで開発環境をシングルバイナリにする

    2026年4月8日

    VPSで開発環境を構築する方法を調べている時にnix-portableでdevShellをbundleできることを発見したので試してみた。 この方法を使うと開発環境を単一バイナリにできる。

    概要

    nix bundleを用いて開発環境を提供するderivationを単一バイナリにbundleする。 mkShellはderivationを提供しないため、devshellの定義にはnumtide/devshellを使用する。

    やり方

    • numtide/devshellを使用してdevShellを定義したflakeを用意する。この時、packagespkgs.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と比較して貧弱。

    ko-fi ☕GitHub Sponsors 🐙