How to run chown for docker image built with streamLayeredImage (or buildLayeredImage)?

Running chown inside extraCommands results in “Operation not permitted” error or “Invalid argument” error (if nix is installed with --daemon), probably because the user is not running as root when building a docker image.

pkgs.dockerTools.streamLayeredImage {
# ... other configs ...
  extraCommands = ''
    mkdir -p ./home/jenkins/agent
    mkdir -p ./home/jenkins/.jenkins
    chown --verbose -R 1000:1000 ./home/jenkins
  '';
}
chown: changing ownership of './home/jenkins/agent': Invalid argument
failed to change ownership of './home/jenkins/agent' from nixbld:nixbld to 1000:1000
chown: changing ownership of './home/jenkins/.jenkins': Invalid argument
failed to change ownership of './home/jenkins/.jenkins' from nixbld:nixbld to 1000:1000
chown: changing ownership of './home/jenkins': Invalid argument
failed to change ownership of './home/jenkins' from nixbld:nixbld to 1000:1000

Only workaround I can think of is creating a Dockerfile to add directories I need. Is there a way to do this without using a Dockerfile? Ideally I don’t want to use 2 tools (nix and Dockerfile) to build a docker image.
dockerTools.buildImage supports runAsRoot but requires kvm capability to work (which my CI server lacks), and the image built with this function is much bigger than one built with stream(build) layeredImage.

https://github.com/NixOS/nixpkgs/issues/94636
https://github.com/NixOS/nixpkgs/issues/67079

I’ve just learned how dockerTools.streamImage works internally by reading source code of nixpkgs…

Final docker image is composed of 2 layers at minimum: One for nix store content, and one for customization layer. Customization layer contains symlinks to store content (/nix/store) and files/directories created with extraCommands argument.

Since customization layer is just a tar archive created with tar command, I could modify owners of its contents, if command for creating tar archive is customizable. Unfortunately it’s not customizable at the moment.

https://github.com/NixOS/nixpkgs/blob/8463b9959d888ce70d07fdd1cb1e9c62ce2e6dd2/pkgs/build-support/docker/default.nix#L767-L782

Files are always owned by root because of hardcoded “–owner 0 --group 0” option.
Could we expose this as “tarCommand” option? With that, I could probably use something like fakeroot before tar to change owner of files to a non-root user.

I implemented a feature that allows modifying owners of files created by customization layer.
Instead of allowing customizing tar command, I just changed tar command to run inside fakeroot, and allowed running arbitrary command (fakeRootCommands) before tar.

By running chown inside fakeroot environment, you can set owner of any files in the archive. fakeroot thinks that files are owned by root if you don’t specify fakeRootCommands.

https://github.com/NixOS/nixpkgs/pull/116749