I’m doing something close to, when building a docker image with nix:
wrappedprogram = pkgs.runCommand "program"
{
buildInputs = [ pkgs.makeWrapper ];
}
''
mkdir -p $out/bin
cp ${program.bin}/bin/program $out/bin
wrapProgram $out/bin/program --prefix PATH : ${pkgs.lib.makeBinPath [
top.pkgs.nix
top.pkgs.openssh
]}
'';
runprogram = pkgs.writeScriptBin "runprogram" ''
nix-channel --add https://nixos.org/channels/nixos-22.11 nixpkgs
nix-channel --update
exec ${wrappedprogram}/bin/program --ssh-config ${sshConfig}
'';
in {
EntryPoint = ["/usr/bin/bash" "-l" "${runprogram}/bin/runprogram"];
The docker image is built and program
runs as expected. program
actually invokes nix-build during its lifetime.
At some point, I’m invoking nix-gc
in the container, to regain some disk space. This cleans up almost everything, including openssh, program, and other deps.
My initial idea would be to add gc-roots at the beginning of “runprogram”:
runOrthanc = pkgs.writeScriptBin "runprogram" ''
# Feels like a hack
ln -s ${wrappedprogram} /nix/var/nix/gcroots/program
ln -s ${sshConfig} /nix/var/nix/gcroots/ssh-config
nix-channel --add https://nixos.org/channels/nixos-22.11 nixpkgs
...
Unfortunately, these roots are ignored. Basically, if I try and print these after the container is up and running:
[root@583938f039c2 /]# nix-store --gc --print-roots
skipping invalid root from '/nix/var/nix/gcroots/program' to '/nix/store/av1i77mf4211cg60g1217700gq76p0p4-program'
skipping invalid root from '/nix/var/nix/gcroots/ssh-config' to '/nix/store/5wzhajpkbylbkzqnw937qbl1drj8nvdc-ssh.config'
So, what makes a gc root invalid? And how do I make it so that these paths are not collected during a garbage collection run?