echo
is a shell built-in, not a binary, so that won’t work. There is no “echo” binary to run, you’d need to launch a shell and call the echo command.
~~Have another look at section 14.2.2.1 here (bit down, linking paragraphs is hard on mobile): https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-dockerTools.~~
I.e., your binaries will be in /bin
. You can just create a PATH variable with config.Env
like so:
pkgs.dockerTools.buildLayeredImage {
config = {
Env = [ "PATH=/bin" ]; # Yeah, ugly, but that's the spec
};
}
I’m not sure if that’s enough to make the binaries callable from Cmd
without specifying their full path either, since that doesn’t go through a shell and therefore probably shouldn’t resolve binaries through PATH
, but docker likes adding magic. If your playwright script respects PATH
that should do the trick, though.
To call packages in Cmd
like your node
there you probably want to use the ${pkgs.nodejs}/bin/node
shortcut as the binary as described a bit further down in the manual. That will automatically include the binary in the image and resolve the command correctly.
I also suspect your working directory may be muddled a bit, how about just using absolute paths like this:
pkgs.dockerTools.buildLayeredImage {
name = "portfolio-pdf";
tag = "latest";
fromImage = playwright;
extraCommands = ''
cp -r "${package}" "/app"
'';
config = {
Cmd = [ "${pkgs.nodejs-16_x}/bin/node" "./dist/index.js" ];
WorkingDir = "/app";
};
}
I’d also suggest making a proper derivation from your package
and adding that to contents instead of copying with extraCommands
, that way you don’t need to spin up qemu just to copy a directory 
Finally, to unconfuse your path situation, in case my guesswork is wrong, note that docker exec -it /bin/ash
exists, as well as docker run -it /bin/ash
, assuming you have the ash shell in the image - that would allow you to inspect the directory tree and debug that way. You can add ash to the contents temporarily by adding busybox
to your contents.
Alternatively, you can export and inspect the tar directly using docker export
.
Ignore me, @c00w is right, I somehow missed that you’re calling that through extraCommands
. echo
is still a shell builtin though.