Nix で Deprecated or EOL なパッケージを導入する
こんにちは. Funds のサーバーサイドエンジニアの上村です. 前回, Nix の記事を書いたのですが実運用上で困る問題を取り上げていなかったので補足編です.
開発現場のありふれた問題として, 外部に公開しないちょっとしたツールなどは対応の優先度が下がり依存関係の更新が疎かになります. 対して, Nix の Stable Channel は EOL バージョンに対応していない傾向があります. 背水の陣の心意気が良いですね 👍 では, そんな時にどうするか 🤔
古いバージョンのパッケージを導入する
NixOS Search で公開されなくなった古いバージョンから目的のパッケージを抽出します. 古いバージョンは Nix Packages Versions から検索できます. 感謝!
Node.js を例として, 下記が古いバージョンのパッケージを抽出する flake.nix になります.
# 一部抜粋
utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
oldPkgs = import
(builtins.fetchGit {
name = "nix-archive";
url = "https://github.com/NixOS/nixpkgs/";
ref = "refs/heads/nixpkgs-unstable";
rev = "7a339d87931bba829f68e94621536cad9132971a";
})
{ inherit system; };
nodejs_20_11_0 = oldPkgs.elmPackages.nodejs;
in
自分でパッケージを作る
Nix packages version で目的のパッケージバージョンが見つからなかったらどうしましょうか 🤔 自分でパッケージ ( Derivation ) を作ってしまいましょう!
Node.js を例に説明すると https://nodejs.org/dist/ に各バージョンのバイナリが公開されています. このバイナリを用いて自分用のパッケージ ( Derivation ) を作ります.
こちらの記事が参考になります.
下記が自分用にパッケージ ( Derivation ) を宣言した flake.nix になります.
# 一部抜粋
let
nodejs_16_16_0 = pkgs.stdenv.mkDerivation {
name = "nodejs16.16.0";
src = pkgs.fetchurl {
url = "https://nodejs.org/dist/v16.16.0/node-v16.16.0-darwin-x64.tar.gz";
sha256 = "sha256-mC7dD602Stbi1yFhZxVEq5OZvQyoxya9480Hd1xMcJo=";
};
installPhase = ''
echo "installing nodejs"
mkdir -p $out
cp -r ./ $out/
'';
};
in
個人で使用する範囲においては特定の Platform に対応するだけで十分です. 複数 Platform に対応したい場合は各 Platform 毎の Derivation を作成します.
そもそも論
上記で紹介した手法は Workaround なので問題の先送りでしかありません. 素直に依存関係のバージョンをあげることに注力した方が良いですね.
ファンズのシステム開発では QA チームの協力を得て定期的に依存関係を更新・確認する体制になっています. 素晴らしいですね 👍
採用情報
堅牢なシステム開発にご興味がある方はぜひご覧ください!