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

    2025年12月17日

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

    nix bundle

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

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

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

    nix bundle 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 🐙