• NixでGleam(Erlang)をシングルバイナリにする

    2025年12月17日

    この記事はNixアドベントカレンダー日目の記事です。

    nix bundle

    Nixにはnix bundleというUnstableながら便利なコマンドがあります。

    これはNixの依存関係を単一のバイナリにまとめ、単一の実行ファイルを生成できるというものです。

    例えば、以下のコマンドを実行すると単一のPython 3.14バイナリが生成されます。

    nix bundle --bundler github:ralismark/nix-appimage nixpkgs#python314

    bundler

    --bundlerオプションを指定すると、バンドルするアルゴリズムを変更できます。 例えば、github:ralismark/nix-appimageと指定すればAppImageとしてシングルバイナリを生成できます。

    さきほどのPython 3.14をAppImageでバンドルするにはこうします。

    nix bundle --bundler github:ralismark/nix-appimage nixpkgs#python314

    AppImageは使用するファイルのみ都度自己解凍する仕組みなので、従来のバンドル方法と比べて起動速度が速いです。 そのため、基本的にはAppImageを用いてバンドルするのがおすすめです。

    Gleamをバンドルする

    これまでGleamでシングルバイナリを生成するにはgarnet等のツールを用いるしかありませんでした。 これはDenoとBunを用いるため、JavaScriptに限定されてしまう問題がありました。

    今回紹介した方法はGleamが使用するランタイムの機能に依存しないため、Erlangもシングルバイナリにできます。 試しにやってみたものがこちらにあります。nix buildで単一バイナリが生成されるはずです。

    GleamプロジェクトをNixでビルドするのにはgleam2nixを使いました。 https://gleam2nix.foxgirl.engineering/

    まとめ

    • nix bundleを使うと任意のpackageを単一バイナリにできる
    • --bundlerオプションでバンドル方法を切り替えられる
    • AppImageを使用すると起動時間の速い単一バイナリが得られる
    • GleamにおけるErlangターゲットなプロジェクトもこれで単一バイナリになる
    • 便利だけどバイナリサイズは結構大きくなる(数百MBとか)

    ko-fi ☕GitHub Sponsors 🐙