DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Boosting React.js Development Productivity With Google Code Assist
  • Chat with Your Oracle Database: SQLcl MCP + GitHub Copilot
  • From 13,000 to 20,000+ Endpoints: Architecting Forensics for the Remote Workforce
  • Mastering GitHub Copilot in VS Code: Ask, Edit, Agent and the Build–Refine–Verify Workflow

Trending

  • Chaos Engineering Has a Blind Spot. Agentic AI Lives in It.
  • Every Cache Miss Is a Tiny Tax on Your Performance
  • Pragmatica Aether: Let Java Be Java
  • Event-Driven Pipelines With Apache Pulsar and Go
  1. DZone
  2. Coding
  3. Tools
  4. VSCode Remote SSH Development With Nix

VSCode Remote SSH Development With Nix

If you are using the VSCode Remote SSH plugin and run on remote NixOS, this article will help you to manage in a declarative way your remote environment.

By 
Ion Mudreac user avatar
Ion Mudreac
·
Sep. 16, 21 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
10.0K Views

Join the DZone community and get the full member experience.

Join For Free

VSCode Remote SSH Development With Nix screenshot.

Context

My team used the VScode Remote SSH plugin to develop applications from Local laptops and remote Google Cloud VM running on NixOS.

Development laptops that the team was using were limited in resources.

From the beginning, we decided to use remote development on NixOs as it allowed us to manage consistency in package management and manage dependency for Python and node.js projects. NixOS is based on nix functional programming configuration language where everything is declarative. All our NixOs configuration was in the git repository.

A good source of the documentation Remote Development using SSH and Remote Development Tips and Tricks.

Problem to Be Solved

During initial testing, we noticed once we try to connect to a remote ssh development environment, we encounter errors due to the nature of Nix.
You can find a good description in the VScode GitHub issue. The workaround that was provided wasn’t elegant for our taste and we strive to automate our infrastructure as code in all aspects and any manual fix wasn’t acceptable.

Solution

After some googling, we found few potential solutions we could implement in nix native expressions: Original solution.
We have two options, both using user Systemd service that monitors /home/$USER/.vscode-server/*.

Separate Repository

Nix flake integration:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixos-vscode-server.url ="github:mudrii/nixos-vscode-ssh-fix/main";
  };

  outputs = inputs@{self, nixpkgs, ...}: {
    nixosConfigurations.some-host = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
          {
            imports = [ inputs.auto-fix-vscode-server.nixosModules.system ];
          }
        ];
      };
  };
}


Nix module:

moduleConfig:
{ lib, pkgs, config, ... }:

with lib;

{
  options.services.nixos-vscode-server = with types;{
    enable = mkEnableOption "auto-fix service for vscode-server in NixOS";
    nodePackage = mkOption {
      type = package;
      default = pkgs.nodejs-14_x;
    };
    findPackage = mkOption {
      type = package;
      default = pkgs.findutils;
    };
  };

  config =
    let
      cfg = config.services.nixos-vscode-server;
      nodePath = "${cfg.nodePackage}/bin/node";
      findPath = "${cfg.findPackage}/bin/find";
      mkStartScript = name: pkgs.writeShellScript "${name}.sh" ''
        set -euo pipefail
        PATH=${makeBinPath (with pkgs; [ coreutils inotify-tools ])}
        bin_dir=~/.vscode-server/bin
        [[ -e $bin_dir ]] &&
        ${findPath} "$bin_dir" -mindepth 2 -maxdepth 2 -name node -type f -exec ln -sfT ${nodePath} {} \; ||
        mkdir -p "$bin_dir"

        while IFS=: read -r bin_dir event; do
          # A new version of the VS Code Server is being created.
          if [[ $event == 'CREATE,ISDIR' ]]; then
            # Create a trigger to know when their node is being created and replace it for our symlink.
            touch "$bin_dir/node"
            inotifywait -qq -e DELETE_SELF "$bin_dir/node"
            ln -sfT ${nodePath} "$bin_dir/node"
          # The monitored directory is deleted, e.g. when "Uninstall VS Code Server from Host" has been run.
          elif [[ $event == DELETE_SELF ]]; then
            # See the comments above Restart in the service config.
            exit 0
          fi
        done < <(inotifywait -q -m -e CREATE,ISDIR -e DELETE_SELF --format '%w%f:%e' "$bin_dir")
      '';
    in
      mkIf cfg.enable (
        moduleConfig rec {
          name = "nixos-vscode-server";
          description = "Automatically fix the VS Code server used by the remote SSH extension";
          serviceConfig = {
            # When a monitored directory is deleted, it will stop being monitored.
            # Even if it is later recreated it will not restart monitoring it.
            # Unfortunately the monitor does not kill itself when it stops monitoring,
            # so rather than creating our own restart mechanism, we leverage systemd to do this for us.
            Restart = "always";
            RestartSec = 0;
            ExecStart = "${mkStartScript name}";
          };
        }
      );
}


Second Solution

Option two is to integrate the Systemd nix service with the existing NixOs home manager configuration as part of the service.
We can reuse the same code as in the nix module.

An example can be found here: git repository.

Note: It's important to make sure you import the service in /home/$USER/.config/nixpkgs/users/$USER/home.nix and enable the service with services.nixos-vscode-ssh-fix.enable = true;.

remote Visual Studio Code

Opinions expressed by DZone contributors are their own.

Related

  • Boosting React.js Development Productivity With Google Code Assist
  • Chat with Your Oracle Database: SQLcl MCP + GitHub Copilot
  • From 13,000 to 20,000+ Endpoints: Architecting Forensics for the Remote Workforce
  • Mastering GitHub Copilot in VS Code: Ask, Edit, Agent and the Build–Refine–Verify Workflow

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook