VSCode Remote WSL extension works on NixOS without patching, thanks to nix-ld

I confirmed that running VSCode Remote extension’s server on NixOS is possible without patching!

The problem is that the extension always tries to use pre-compiled node, which does not work on NixOS out-of-box (fails to run with No such file or directory error). You usually need to patch such binaries manually, reasons explained here:

https://nixos.wiki/wiki/Packaging/Binaries

/home/nixos/.vscode-server/bin/3866c3553be8b268c8a7f8c0482c0c0177aa8bfa/server.sh: line 12: /home/nixos/.vscode-server/bin/3866c3553be8b268c8a7f8c0482c0c0177aa8bfa/node: No such file or directory

nix-ld allows you to run pre-compiled executables on NixOS without patching. As far as I know there is no configurable option of the extension to prefer system-provided node, so I guess this is the least hacky workaround.
Previous workaround I found in NixOS discourse patches node in server-env-setup. Another one in GitHub requires you to edit server install script bundled in the extension.

I installed NixOS to WSL2 with NixOS-WSL. Upgrade to nixos-21.05 before proceeding.

Create nix-ld-config.nix in /etc/nixos. The module configures environment variables for nix-ld, and writes the same value to .vscode-server/server-env-setup, because the server don’t recognize environment variables set by environment.variables option of NixOS. Without that, the server fails to launch with the following errors:

cannot execute /home/nixos/.vscode-server/bin/3866c3553be8b268c8a7f8c0482c0c0177aa8bfa/node: NIX_LD or NIX_LD_x86_64-linux is not set

The module requires home-manager module and nix-ld module to work.

nix-ld-config.nix:

{ lib, pkgs, config, ... }:
with lib;
let
  cfg = config.nix-ld-config;
  ldEnv = {
    NIX_LD_LIBRARY_PATH = with pkgs; makeLibraryPath [
      stdenv.cc.cc
    ];
    NIX_LD = removeSuffix "\n" (builtins.readFile "${pkgs.stdenv.cc}/nix-support/dynamic-linker");
  };
  ldExports = mapAttrsToList (name: value: "export ${name}=${value}") ldEnv;
  joinedLdExports = concatStringsSep "\n" ldExports;
in
{
  options.nix-ld-config = {
    enable = mkEnableOption "nix-ld config module";
    user = mkOption {
      type = types.str;
      description = "The name of user you want to configure for using VSCode's Remote WSL extension.";
      default = "nixos";
    };
  };
  config = mkIf cfg.enable {
    environment.variables = ldEnv;
    home-manager.users.${cfg.user}.home.file.".vscode-server/server-env-setup".text = joinedLdExports;
  };
}

Add imports, wget package, and configuration for nix-ld-config module to your configuration.nix. wget is required for fetching VSCode extension’s dependencies. If you are using user name other than default one (nixos), then adjust nix-ld-config.user option.

configuration.nix:

{
  imports = [
    "${modulesPath}/profiles/minimal.nix" # This one is already there when you install NixOS
    <nix-ld/modules/nix-ld.nix>
    <home-manager/nixos>
    ./nix-ld-config.nix
  ];
  environment.systemPackages = with pkgs; [
    wget
  ];
  nix-ld-config.enable = true;
}

add channels and run nixos-rebuild switch.

sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
sudo nix-channel --add https://github.com/Mic92/nix-ld/archive/main.tar.gz nix-ld
sudo nix-channel --update

Make sure that you have correct channels with sudo nix-channel --list.

home-manager https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz
nix-ld https://github.com/Mic92/nix-ld/archive/main.tar.gz
nixos https://nixos.org/channels/nixos-21.05

Finally, run sudo nixos-rebuild switch

5 Likes