Skip to content

Instantly share code, notes, and snippets.

@slikts
Last active September 4, 2023 07:30
Show Gist options
  • Save slikts/63abbeb63b72b3f515c70258bfc19a44 to your computer and use it in GitHub Desktop.
Save slikts/63abbeb63b72b3f515c70258bfc19a44 to your computer and use it in GitHub Desktop.
Linuxifying Windows

nelabs.dev

Linuxifying Windows for development

This guide is for 'linuxing-up' Windows as a development environment; it focuses on setting up WSL, an Ubuntu Hyper-V virtual machine, wsltty (a nice terminal emulator) and various tweaks.

Rationale

Why use both WSL and a Hyper-V VM

For the same reason why the upcoming WSL version 2 uses Hyper-V – the i/o performance in WSL 1 is several-fold slower than in a VM, which means that build or install processes take longer.

WSL 2 is currently only available in Windows Insider Preview builds, so it's not suitable for users that aren't keen on being early adopters. Linuxifying Windows stable builds will be significantly more simple once WSL 2 is available.

Another notable perk of using a Hyper-V VM over WSL 1 is that the VM's state gets automatically saved when powering off the host, reducing disruption to development.

Why Hyper-V over VirtualBox or VMWare Player

Hyper-V's dynamic memory feature means that a smaller initial amount of memory can be reserved for the guest OS and then automatically increased if required (and also reclaimed later). In comparison, VirtualBox has a "memory ballooning" feature, but it can only re-distribute a fixed amount of memory between guests.

VirtualBox has better support for graphics acceleration in guests, but it's not required when the guests are used as headless servers.

Hyper-V caveats

Enabling Hyper-V prevents the use of VMware or VirtualBox versions prior to VirtualBox 6, because Hyper-V is a Type 1 hypervisor and reserves direct access to the hardware virtualization technology (VT-x or AMD-V).

Hyper-V makes Windows run as a virtualized guest, which adds a 9–12% CPU overhead and a 6–8% i/o overhead and can make a noticeable difference in resource-constrained scenarios (notably, games).

WSL and wsltty

Installation

  1. Chocolatey
  2. wsltty
    choco install wsltty
    
  3. WSL

    Win+R, optionalfeatures, select Windows Subsystem for Linux.

wsltty tweaks

  1. Install the Fira Code font in Windows (contains various special glyphs)
  2. Run wsltty (called "WSL Terminal" in Start Menu)
  3. Right click wsltty window title and select Options
  4. Change theme under Looks (the default theme's blue is too dark to read on black; I use the flat-ui theme)
  5. Under Text, select Fira Code, increase size as required
  6. Under Window, increase the default columns and rows so that the window doesn't need to be resized each time

VS Code Remote Development

Install the Remote Development extension pack in VS Code and it'll allow to just seamlessly run code . in a directory in WSL, and the launched VS Code instance will use tools like git from within WSL, allow running commands in WSL, etc.

Ubuntu Hyper-V virtual machine

Prerequisites

  1. Windows 10 Pro (Home doesn't support Hyper-V), version 1809 or later
  2. Hyper-V enabled in firmware and supported by CPU
  3. Hyper-V

    Win+R, optionalfeatures, select Hyper-V.

Creating the VM

Run Hyper-V Manager, Quick Create…, select Ubuntu 19.04, follow the wizard, run the created virtual machine, finish initial setup with default settings.

Networking tweaks

The virtual machine is only connectable from the host OS by default; to make it connectable from the LAN, an external virtual switch needs to be created:

Hyper-V Manager, Actions, Virtual Switch Manager…, External, Create Virtual Switch, select the NIC connected to LAN.

Hyper-V Manager, Settings… for the created virtual machine, Network Adapter, select the created external virtual switch as the virtual switch.

To make the IP static:

Advanced Features under Network Adapter, select static MAC address radio option.

Autostart

By default the VM will autostart with the OS only if the VM was running when the OS shut down; to make it autostart always:

Settings… for the created virtual machine, Automatic Start Action under Management, Always start this virtual machine automatically.

Sharing files with host OS

In VM terminal:

sudo apt install samba
sudo vim /etc/samba/smb.conf

Uncomment [homes] section and change read only to no under it.

sudo systemctl restart nmbd
smbpasswd -a your_username

In Windows:

This PC, Computer, Map Network Drive, enter \\vm_host_name\your_username

VS Code Remote Development

  1. Install the Remote Development extension pack in VS Code
  2. Install Windows OpenSSH Client
  3. Run ssh-keygen -b 4096 from Windows command line and choose the defaults
  4. Copy the contents of %USERPROFILE%\.ssh\id_rsa.pub to ~/.ssh/authorized_keys in the VM
  5. Run chmod 600 ~/.ssh/authorized_keys in the VM
  6. Go to Remote-SSH in VS Code, choose %USERPROFILE%\.ssh\config and enter the VM host name

The same steps to set up SSH connections from Windows could also be repeated within WSL.

Running Ubuntu without desktop environment

sudo systemctl set-default multi-user.target

tmux shortcuts

Run sudo apt install tmux in either the VM or WSL.

Windows shortcut target to automatically connect to a tmux session named 'main' in WSL:

%LocalAppData%\wsltty\bin\mintty.exe --WSL= --configdir="C:\Users\dabas\AppData\Roaming\wsltty" -~ -R o -e tmux new -A -s main

Windows shortcut target to automatically connect to a tmux session named 'main' in the VM (replace VM_HOST_NAME):

%LocalAppData%\wsltty\bin\mintty.exe --WSL= --configdir="C:\Users\dabas\AppData\Roaming\wsltty" -~ -R o -e ssh -t <VM_HOST_NAME> "tmux new -A -s main"

Different icons can be set for the shortcuts to make telling the VM and WSL terminals apart easier when both are running.

@BrandonTheMandon
Copy link

This was a super-helpful guide. Thanks for posting it :)

I agree with the sentiment of qdm12. Adding some basic steps for configuring Docker would be interesting.

@qdm12
Copy link

qdm12 commented Aug 12, 2019

In the end, now that VS Code supports remote development with containers (and descriptive files per project!), the best is to simply install the Docker Desktop program and run your development inside containers (so technically in the mobyvm Hyper-V OS).

A Hyper-V custom machine can be useful to test Linux specific features such as Kernel modules dependant programs. But a custom Hyper-V Linux with Docker can be hard to be configured to support host bind mounts making VS code remote development almost impossible.

When WSL 2 is released, running everything there with a good Docker integration can be interesting, although the performance will likely be the same as it is now with mobyVm.

@slikts
Copy link
Author

slikts commented Sep 6, 2019

One possibility is that the IP is changing because the DHCP server isn't configured for IP and MAC binding.

@slikts
Copy link
Author

slikts commented Oct 30, 2019

I took the plunge to switch to Fast ring Insiders and try WSL 2, and it broke things: 3D applications were stuttering and all the typography became pixellated and hard to read, so it's back to waiting for a more stable release.

@slikts
Copy link
Author

slikts commented Nov 4, 2019

Added a section for Hyper-V caveats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment