Using Bazel with rules_docker in NixOS

It seems rules_docker download a dynamically linked go binary that doesn’t work in NixOS, as the binary points to libraries in places that don’t exist in NixOS. The NixOS wiki has an example of using buildFHSUserEnv to work around that.

Based on the NixOS Wiki, I created a shell.nix with the following contents:

 { pkgs ? import <nixpkgs> {} }:
 
 (pkgs.buildFHSUserEnv {
   name = "bazel-userenv-example";
   targetPkgs = pkgs: [
     pkgs.bazel_4
   ];
 }).env

I ran nix-shell and tried to bazel build a container_image rule. This would fail with

ERROR: An error occurred during the fetch of repository 'bazel_gazelle_go_repository_tools':
   Traceback (most recent call last):
	File "/home/heidbrij/.cache/bazel/_bazel_heidbrij/d911c00b1dabff82a87b324fcfe0e553/external/bazel_gazelle/internal/go_repository_tools.bzl", line 84, column 17, in _go_repository_tools_impl
		fail("list_repository_tools_srcs: " + result.stderr)
Error in fail: list_repository_tools_srcs: env: '/home/heidbrij/.cache/bazel/_bazel_heidbrij/d911c00b1dabff82a87b324fcfe0e553/external/go_sdk/bin/go': No such file or directory

From the nix-shell environment, I could however run the mentioned go binary and it would show me the help screen. From outside of the nix-shell environment, I could not run it, but would also get the “No such file or directory”. I would expect that since I can call it from within the nix-shell, the bazel build should also be fine. Is someone using the example from the Wiki and has it working?

I tried it again and it worked straight away.

I assume what happened is:

On my first naive attempt to build an image using rules_docker, the bazel CLI started a server, and delegated the build to the server. That server couldn’t run the downloaded go binary, and the bazel build failed. Afterwards I applied the workaround from the NixOS Wiki. Now the bazel client would run in the FHSUserEnv, but as the server was still running, the client would connect to running server. The existing server process was still running in an environment where it couldn’t execute the go binary, so the bazel build failed again.