nix-community / NixOS-WSL

NixOS on WSL(2) [maintainer=@nzbr]
Apache License 2.0
1.93k stars 120 forks source link

Docs: complete process for how to use VSCode #294

Closed gabrielgrant closed 2 months ago

gabrielgrant commented 1 year ago

Problem

On WSL with a fresh Ubuntu install, running code . works to make the distro immediately useful. On NixOS there are a number of decisions to be made and issues to be overcome before being able to use the distro for dev work. The info about this process is scattered across a number of issues (see below) and discussions in this repo, plus NixOS wiki pages, the NixOS discourse and other repos.

A lot of this information is conflicting and/or outdated.

Relevant issues for initial VSCode install/setup process:

Background: I am a complete noob to NixOS (though I have 15+ years of Linux and software dev experience). The ideas behind Nix are appealing, so thought I'd try it out for some dev work via WSL to get acquainted. When starting NixOS on WSL for the first time, the first task I tried to achieve (after upgrading) was to get a working dev env up and running, including VSCode. Unfortunately, even after eventually reading all the resources listed above, I still haven't achieved a fully-working VSCode install & dev setup I'm comfortable with (so have had to revert to Ubuntu for the time being)

Virtually everyone I know using WSL is also using VSCode, so this seems like an extremely common first step for new installers. AFAICT at least some of the kindly folks working on NixOS-WSL (including @nzbr ) are using vscode successfully (there is a .vscode dir in the repo root). So would be very helpful to have their knowledge/opinions distilled into ...

Solution

An authoritative set of clear, concise, up-to-date, step-by-step/end-to-end instructions on how to go from a fresh install to a working dev env with VSCode. Ideally this would be in this repo, linked from the README and effectively considered part of the initial install instructions

Specific questions to address:

K900 commented 1 year ago

I've had a workaround for this for a while that I never got around to publishing, but now I did: https://github.com/K900/vscode-remote-workaround

This should be enough to get things working without any extra movements, no matter what setup you're using.

acelinkio commented 1 year ago

Got vscode wsl remoting with NixOS to work. This is using the nix-ld approach

Version Info

Windows 11 22H2
WSL version 1.2.5.0
vscode 1.83.1 (user setup)
ms-vscode-remote.remote-wsl-0.81.8

Setup Instructions

Thoughts

Changing wslDaemon.js as mentioned https://nixos.wiki/wiki/Visual_Studio_Code#Remote_WSL did nothing. My guess is that that file is versioned outside of the wsl extension. No amount of changing versions or restarting vscode helped. The underlying wsl remoting commands being executed did not respect any modifications.

Really would like to see this user experience improved. Most of this appears to have been caused by the VSCode WSL extension changes. Closest issue I could find is https://github.com/microsoft/vscode-remote-release/issues/8305

cc @Atry @sonowz

sonowz commented 1 year ago

I believe the solutions mentioned above should have worked before Remote-WSL 0.77.0, which broke all the solutions and caused https://github.com/microsoft/vscode-remote-release/issues/8305. Downgrading the extension below 0.76.1 until the issue is resolved should work in most cases. However the current situation of every users stumbling upon this issue is absolutely frustrating :(

Atry commented 1 year ago

I think we can use the fallback path since https://github.com/Mic92/nix-ld/pull/53

acelinkio commented 1 year ago

Here's the simplest solution I have found so far. On a fresh wsl instance, put this flake somewhere and then apply via sudo nixos-rebuild switch --flake .

flake.nix

{
  description = "SpecialSnowflake";

  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
  inputs.nixoswsl.url = "github:nix-community/NixOS-WSL";
  inputs.nixoswsl.inputs.nixpkgs.follows = "nixpkgs";
  inputs.vscode-server.url = "github:nix-community/nixos-vscode-server";
  outputs = { 
    self,
    nixpkgs,
    nixoswsl,
    vscode-server,
    ...
    }: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        nixoswsl.nixosModules.wsl
        vscode-server.nixosModules.default
        ({ pkgs, ... }: {
          system = {
            stateVersion = "23.05";
          };
          programs.nix-ld.enable = true;
          services.vscode-server.enable = true;
          environment.systemPackages = [
            pkgs.wget
          ];

          wsl = {
            enable = true;
            defaultUser = "nixos";
            extraBin = with pkgs; [
              { src = "${coreutils}/bin/uname"; }
              { src = "${coreutils}/bin/dirname"; }
              { src = "${coreutils}/bin/readlink"; }
            ];
          };
        })
      ];
    };
  };
}
wsl --terminate NixOs
wsl --distribution NixOs
code .

For anyone trying to create solutions, be sure to document how to get things started. Trying to do first run from VSCode starting a WSL remote connection leads to errors with another group of missing tools.

referencing https://github.com/nix-community/nixos-vscode-server/issues/67 as this has been the simplest flake so far. I did not have luck with others.

SuperSandro2000 commented 1 year ago

I really do not want to enable nix-ld as it changes LD_LIBRARY_PATH for everything which can lead to weird bugs in my experience.

Atry commented 1 year ago

nix-ld-rs behaves differently

On Thu, Nov 9, 2023 at 2:37 AM Sandro @.***> wrote:

I really do not want to enable nix-ld as it changes LD_LIBRARY_PATH for everything which can lead to weird bugs in my experience.

— Reply to this email directly, view it on GitHub https://github.com/nix-community/NixOS-WSL/issues/294#issuecomment-1803579960, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAES3ORRXQDWDKHSLZUOVZLYDSXAPAVCNFSM6AAAAAA5HT3IOOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMBTGU3TSOJWGA . You are receiving this because you were mentioned.Message ID: @.***>

fyang93 commented 11 months ago

Here's the simplest solution I have found so far. On a fresh wsl instance, put this flake somewhere and then apply via sudo nixos-rebuild switch --flake .

flake.nix

{
  description = "SpecialSnowflake";

  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
  inputs.nixoswsl.url = "github:nix-community/NixOS-WSL";
  inputs.nixoswsl.inputs.nixpkgs.follows = "nixpkgs";
  inputs.vscode-server.url = "github:nix-community/nixos-vscode-server";
  outputs = { 
    self,
    nixpkgs,
    nixoswsl,
    vscode-server,
    ...
    }: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        nixoswsl.nixosModules.wsl
        vscode-server.nixosModules.default
        ({ pkgs, ... }: {
          system = {
            stateVersion = "23.05";
          };
          programs.nix-ld.enable = true;
          services.vscode-server.enable = true;
          environment.systemPackages = [
            pkgs.wget
          ];

          wsl = {
            enable = true;
            defaultUser = "nixos";
            extraBin = with pkgs; [
              { src = "${coreutils}/bin/uname"; }
              { src = "${coreutils}/bin/dirname"; }
              { src = "${coreutils}/bin/readlink"; }
            ];
          };
        })
      ];
    };
  };
}
wsl --terminate NixOs
wsl --distribution NixOs
code .

For anyone trying to create solutions, be sure to document how to get things started. Trying to do first run from VSCode starting a WSL remote connection leads to errors with another group of missing tools.

referencing nix-community/nixos-vscode-server#67 as this has been the simplest flake so far. I did not have luck with others.

@acelinkio Thank you for providing the solution; it enabled me to successfully run VSCode in WSL. However, I encountered an issue when attempting to launch a devcontainer or attach to a running Docker container inside WSL. The following error message persists:

[202907 ms] Dev Containers 0.327.0 in VS Code 1.85.0 (af28b32d7e553898b2a91af498b1fb666fdebe0c).
[202906 ms] Start: Run: wsl -d NixOS -e /bin/sh -c cd '/home/nixos/nix-wsl' && /bin/sh
[202912 ms] Start: Run in host: id -un
[203012 ms] 
[203012 ms] /nix/store/5q96kfjc8bxwv89fw0fqczwr6083ny8n-bash-interactive-5.2-p15/bin/sh: line 1: id: command not found
[203012 ms] Exit code 127

Upon investigation, I found that the issue lies in the $PATH environment variable, which lacks /run/current-system/sw/bin where almost all the necessary binaries are located. It seems that wsl -d NixOS -e /bin/sh leads to a non-login shell, resulting in a different $PATH compared to a login shell. May I ask if you have any solutions or suggestions?

acelinkio commented 11 months ago

@fyang93

I don't know how Docker based container remoting works when inside WSL. Afaik the connection is made by invoking the wsl.exe binary, but the commands passed through expect the docker/container binary to be accessible. You can try to expose those via extraBin like for uname/dirname/readlink.

I successfully got the remoting working with kuberenetes by directly point the kubernetes api server that is hosted WSL. Doing it this way avoids leveraging the wsl.exe

Atry commented 11 months ago

I would try nix-ld-rs + server-env-setup approach. I created some NixOS modules in that approach here: https://github.com/Atry/nixos-wsl-vscode

carschandler commented 9 months ago

Does anyone have a lightweight solution to this issue that doesn't require nix-ld?

acelinkio commented 9 months ago

There are two small errors that happened with recent versions of vscode. One is with not being able to locate cat or sed which can be fixed via adding those to the wsl extraBin via appending on

{ src = "${coreutils}/bin/cat"; }
{ src = "${coreutils}/bin/sed"; }
{ src = "/run/current-system/sw/bin/sed"; }

After exploring @rodent1 nix configuration, there is a more direct fix that allows wsl remoting to be opened by Windows or Nixos. Creating a configuration ~/.vscode-server/server-env-setup file with the following contents. This still requires nix-ld/nix-ld-rs and wsl should be restarted after setup.

PATH=$PATH:/run/current-system/sw/bin/

Reference for how I implemented https://github.com/acelinkio/nixplayground/blob/main/wsl/flake.nix

Docs: https://code.visualstudio.com/docs/remote/wsl#_advanced-environment-setup-script

InaccurateTank commented 8 months ago

I tried the ~/.vscode-server/server-env-setup fix and I don't think you even need the extraBin arguments when running it. At least with nix-ld-rs. You do however still need to install wget.

eg nixos config

wsl = {
  enable = true;
  defaultUser = "nixos";
 };

environment.systemPackages = with pkgs; [
  wget
];

programs.nix-ld = {
  enable = true;
  package = inputs.nix-ld-rs.packages.${pkgs.system}.default;
};

Honestly it doesn't look like you even need vscode-server with it.

songpola commented 8 months ago

Hello. I've summed up and tested the minimum WSL2 NixOS config that make VSCode Remote works.

flake.nix:

{
  inputs = {
    nixpkgs.url = "nixpkgs";
    nixos-wsl = {
      url = "github:nix-community/NixOS-WSL";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-ld-rs = {
      url = "github:nix-community/nix-ld-rs";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: with inputs; {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [
        nixos-wsl.nixosModules.default
        ./configuration.nix
      ];
    };
  };
}

configuration.nix:

{
  wsl = {
    enable = true;
    defaultUser = "nixos";
  };

  nix.settings.experimental-features = [ "nix-command" "flakes" ];

  programs.nix-ld = {
    enable = true;
    package = inputs.nix-ld-rs.packages."${pkgs.system}".nix-ld-rs;
  };
}

~/.vscode-server/server-env-setup:

PATH=$PATH:/run/current-system/sw/bin/

Hope it will be helpful!

Edited: Removed unnecessary micro text editor

Update: Today (2024-04-28), I tried the setup again and found that it works even without the ~/.vscode-server/server-env-setup

SuperSandro2000 commented 8 months ago

Why micro? I don't think we need that.

songpola commented 8 months ago

Sorry, it's just a text editor I used. Removed.

0xLunch commented 8 months ago

Above solution by @songpola fixed NixOS WSL and VSCode Insiders for me. Insiders can now successfully open remote connection to WSL both by running 'code-insiders .' within WSL directory, and by launching VSCode in Windows and connecting.

songpola commented 8 months ago

Above solution by @songpola fixed NixOS WSL and VSCode Insiders for me. Insiders can now successfully open remote connection to WSL both by running 'code-insiders .' within WSL directory, and by launching VSCode in Windows and connecting.

I use the stable one. Glad it helps with Insider one too!

0xLunch commented 8 months ago

Hmm, I did a fresh install recently and now for some reason after going into my project directory, running nix develop to activate the flake then code . to open it... vscode does not gain the flake environment rendering my IDE useless since can't access binaries and language servers.

Not sure what happened. Pretty sure it worked just fine on the previous installation.

JanuszSamborski commented 7 months ago

@0xLunch Have you by any chance found a solution? I just freshly installed nix and got VsCode working and I have the exact same problem.

Edit2: It seems like none of the exported environment variables - including ones set via nix shell are passed to vscode. If I run export foo=bar ; code . in ubuntu, echo $foo yields bar. If I do the same thing in nix - foo isn't set.

Edit3: So my current solution is to add

  shellHook =
    ''
      WSLENV=$WSLENV:PATH
    '';

to my shell.nix - it exposes PATH to process running in vscode, which helps with most extensions

songpola commented 7 months ago

Update: Today, I tried the setup again and found that it works even without the ~/.vscode-server/server-env-setup

PorcoRosso85 commented 6 months ago

Hmm, I did a fresh install recently and now for some reason after going into my project directory, running nix develop to activate the flake then code . to open it... vscode does not gain the flake environment rendering my IDE useless since can't access binaries and language servers.

Not sure what happened. Pretty sure it worked just fine on the previous installation.

+1

I just want vscode server to run with entering nix develop shell/virtual env btw, other tool, such as devbox, devenv, will work. this means that vscode server will start inside of virtual env

PorcoRosso85 commented 6 months ago

@JanuszSamborski

On Mac, this solution will work as same?

arraen commented 6 months ago

With @songpola config, I'm getting such an error:

`error: undefined variable 'inputs'

   at /nix/store/6z15vxc9dxjjj5573c5q13h3sfavwdhb-source/configuration.nix:17:15:

       16|     enable = true;
       17|     package = inputs.nix-ld-rs.packages."${pkgs.system}".nix-ld-rs;
         |               ^
       18|   };`
carschandler commented 6 months ago

@arraen make sure you are passing the inputs properly in your flake

  outputs = inputs: with inputs; {
# IMPORTANT ^^^^^^^^^^^^^^^^^^^
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
# IMPORTANT           ^^^^^^^^^^^^^^
      modules = [
        nixos-wsl.nixosModules.default
        ./configuration.nix
      ];
    };
  };
arraen commented 6 months ago

@carschandler Yes, I copied both configs and put them into fresh wsl. I'm new with Nixos, so maybe this issue is obvious for more experienced users, but I need to add inputs to head of configuration.nix: { config, lib, pkgs, inputs, ... }:

*Also, you should have wget installed :)

PS Additionally, in flake.nix I set: nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; to stop rolling updates.

wyndon commented 3 months ago

I'm a bit confused by the need to use VSCode on the host with the WSL extension in the first place; wouldn't it be better to just use VSCode from WSL directly, since it's possible to use GUI apps + we'd also get to use the VSCode home-manager module ?

K900 commented 3 months ago

Not really, no, because WSLg is far from perfect, is currently not very fast (though that is something that could be addressed on the NixOS side to an extent), and isn't always enabled.

nan-mu commented 2 months ago

For this time period, I think it is necessary to update the documentation

After several hours of trying, I can now prove that the method mentioned in https://github.com/sonowz/vscode-remote-wsl-nixos is completely usable except for a small flaw. I may upload all the configuration files later but I think everything mentioned in this repository can solve the problems you encounter (only wget is needed, not K900 and nix-ld solutions).

Ok, the url https://github.com/nan-mu/nixos-config

nan-mu commented 2 months ago

If possible, I'd like to write a document about this, but I see a lot of similar pull requests are open? Any plans for documentation?

SuperSandro2000 commented 2 months ago

There is a file on now to run vscode remote server. https://github.com/nix-community/NixOS-WSL/blob/main/docs/src/how-to/vscode.md

nan-mu commented 2 months ago

There is a file on now to run vscode remote server. https://github.com/nix-community/NixOS-WSL/blob/main/docs/src/how-to/vscode.md

The strange thing is that both methods didn't work after trying them. There are somethings, for example, it seems that nix-ld-rs has been merged into nix-ld, and I can't find the functions mentioned in the documentation for the latest version. Also, K900's solution reported a socket timeout error in vscode side. I think these errors are not difficult to reproduce.

songpola commented 2 months ago

@nan-mu For the latest version (unstable), you can just enable only the programs.nix-ld.enable option. No need to specify the package.

nan-mu commented 2 months ago

@nan-mu For the latest version (unstable), you can just enable only the programs.nix-ld.enable option. No need to specify the package.

Thanks, I tried that too. But it seems like don't work for me.

yipengsun commented 2 months ago

I just had the same issue today, and your workaround works for me. Thanks!

BTW, if you have nix-direnv set up, installing the direnv VS Code extension to the WSL host seems to make these devShell-set env vars propagate to VS Code.

  shellHook =
    ''
      WSLENV=$WSLENV:PATH
    '';

to my shell.nix - it exposes PATH to process running in vscode, which helps with most extensions