3行まとめ
- nixは羃等性のあるビルドができる
- nixには組み込みで羃等性のあるビルドができる特性を活かしてリモートのマシンでビルドを代行できる機能がある
- リモートでnixレシピをビルドするマシンを提供するサービスとしてnixbuildが便利
Nixのビルドは重い(時もある)
Nixはその性質上、基本依存するパッケージを全てビルドします。 よく使われるパッケージはnixpkgsなどでcacheが存在しているため、ビルドをスキップできます。 しかし、Rustで書かれたパッケージなど依存をキャッシュしていてもビルドが重いパッケージなども往々にして存在します。 そんな時に使えるサービスとしてnixbuildが使えます。
nixbuildについて
NixにはRemote Buildsと呼ばれる仕組みが存在します。 このRemote BuildsはNixのビルドを手元ではなく、リモートマシンで実行することにより手元でのビルド負荷を軽減できる仕組みです。 Nixは純粋関数型パッケージマネージャなので、どのマシンでビルドしても同等の結果を受け取れるという性質がよく活きている機能ですね。
また、nixbuildはマトリックスビルドに対応してるので、darwin向けのビルドもLinux向けのビルドも特別な設定を必要とせず行えるというメリットもあります。
使用方法
利用にはメールアドレスとSSH、PayPalのアカウントが必要です。 後述しますが、PayPalのアカウントは住所を登録する必要があります。住所が登録されていない場合サービスが停止されます。
まず以下のサイトにアクセスしアカウントを作成してください。 nixbuildは認証にパスワードではなくメールアドレスを使用するため、サイトにパスワードを設定する必要はありません。(最近こういうサイト増えましたね…ありがたい)
アカウントを作成した後は設定画面から公開鍵を登録してください。 nixbuild側の設定が終わった後はNixOS側も設定します。
設定方法については公式ドキュメントに書いてあります。 英語ですがこれ読めば多分設定できるはずです。分かりづらい点があったら後日追記します。
料金について
毎月24CPU時間のクレジットが付与され、クレジットを使い切ると従量課金で請求が始まります。 料金はユーロで請求されるので支払額は為替の影響を受けますが、請求のあった月は800円くらい取られた気がします。 毎週NixOSの更新をしてこの額なので結構お安いなと思ってます。 また、NixはHashが同一の場合はビルドを行わないので、無駄にビルドをして料金が嵩むといった現象が起こりづらいため、その点も料金が最適化される要因かなと思ってます。
料金の確認方法
料金の確認方法ですが、なんとSSH経由で確認する必要があります。 ユーザーを信頼しすぎだろ…と思いますが慣れると結構使いやすいです。
まず以下のコマンドでnixbuildにSSH接続します。 対象のアカウントはSSH公開鍵を指定したアカウントとなります。
ssh -T eu.nixbuild.netよく使いそうなコマンドを以下に書いてみました。
usage # リソースの使用量を確認する
builds list # ビルド結果の一覧を表示する
billing info # 料金を確認するためのPayPalページのURLを表示する
token create # nixbuildへアクセスするためのAPI Tokenを作成する注意点
PayPalの住所は設定した方が良い
利用には住所の確認が必要(決済の都合上必要とのこと)なのですが、PayPalのアカウントに設定されているものを参照するため、PayPalに住所が設定さていない場合はしばらくしてサービスが停止されます。 これを会場するにはnixbuild運営に英語で住所を記載したメールを送信する必要があります。これがまぁ〜面倒なのでみなさんは登録する前にPayPalに住所を登録しておいてください…
機密情報を含むコードは--builders ''を指定した方が良い
nixbuildはリモートサーバーで実行するという都合上、全てのNixパッケージのビルドがリモートマシンで行われます。つまりソースコードを含む情報が問答無用でサーバーへ転送されます。 しかもビルド結果はキャッシュされます。うっかり社内のソースコードを送ってしまった日には社内SEの顔面が真っ青になりますね… ソースコードが送られると書きましたが、厳密にはDerivationを生成するためのClosure1という単位でサーバーへ情報が送信されます。
また、いちいち--buildersオプションを指定したくない場合は以下の環境変数を設定することでビルド時に外部マシンを使用せず全て手元でビルドしたい場合はexport NIX_CONFIG='builders ='を指定してください。
direnvでは~/.config/direnv/direnvrcにbash関数を記述することで複数ディレクトリを対象に環境変数を設定できます。 以下はghqを想定して複数プロジェクトにNIX_CONFIGを設定する例です。
load_nix_config() {
local ghq_root
ghq_root="$(ghq root)"
# nixbuildの対象外にするリポジトリ一覧
# サブディレクトリが対象になるのでユーザ名を指定するとユーザー単位で無効化される
local repos=(
"github.com/user/name"
"github.com/userA/"
)
for repo in "${repos[@]}"; do
repo="${repo%/}"
if [[ "$PWD" == "$ghq_root/$repo" || "$PWD" == "$ghq_root/$repo/"* ]]; then
export NIX_CONFIG=$'builders = ""'
return
fi
done
}
# 定義するのは単純なbash関数なので実行する必要がある
load_nix_configまとめ
今回はNixのビルドサービスnixbuidについて紹介しました。 このサービス個人的に結構気に入ってるので、日本でも広まって欲しいな〜と思ったのと、これがNixを導入するメリットの一つになってくれれば良いなと思ってます。
この記事では触れませんでしたが、nixbuildにはcacheのアップロード先の登録が可能で、cachixと連携ができたします。 このあたりを活用すれば、規模の大きめな開発でもより安定してnix cacheを提供できそうで使い道が広がりそうだな〜と思ったりしてます。