Developing on Windows with WSL2

A picture of a computer screen with VSCode opened on a ruby file. On top of this window, there's a smaller window with 'localhost:3000' as url. The website says 'Yay! You're on Rails!' with the ruby on rails logo above it.

Last week the keyboard of my MacBook Pro broke. One key just stopped working, and I have lived over months with double keystrokes. It was time to bring it to the Apple store and get it fixed. The dude in the Genius Bar told me it would take 10-14 days. Since a new build of Windows with WSL2 (Windows Subsystem for Linux) just got out, I took the chances (and mainly I got nudged by Jacob Dawid who is also trying out WSL2) and tried out a whole new developer experience: Doing Web Development in Windows! And by Web Development I mean fullstack Web Development, that means:

  • Ruby on Rails for the backend (alternatively we use Elixir / Phoenix or Springboot)

  • React for the Frontend (using Webpack with Typescript)

Since the beginning of dawn, web development on Windows was a very painful experience. Especially developing with Ruby on Rails was quite a hell. Most of the dependencies didn't work out of the box, and there were strange heisenbugs all over the place. It got a bit better when Node.js took the world by storm, and Microsoft invested in getting it Node.js working on its platform. But running a huge Jest suite took about ten times longer than running under Linux or OSX. Then Microsoft introduced something intriguing...

Meet Windows Subsystem For Linux (WSL)

WSL was introduced as a compatibility layer for running Linux binary executables natively on Windows. It promised to run a full fledged Linux like Ubuntu side by side with the same kernel. The first iteration of WSL was designed for no hardware emulation / virtualization... and it really sucked. Installing Rails was an even bigger shit than installing it on Windows natively, and when you got it working you failed by installing a decent database like PostgreSQL. With WSL2, they changed strategy by opting for virtualization through a highly optimized subset of Hyper-V features.

Getting WSL2 up & running

For installing WSL2, I mainly followed a tutorial by Scott Hanselmann. The process was not 100% straight forward since it was a bit back and forth getting the latest "Microsoft Insider Build", then updating the Kernel and finally migrating the virtual machines from WSL1 to WSL2.

Protip: If you're unsure which version of WSL you're running then run this command:

bashPS C:\Users\sebas> wsl --list -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2

Installing Rails & Friends

Installing Rails and Postgres was a breeze. Since it's not a quirky emulation syscall hack, installing everything felt like installing it with Ubuntu. The biggest difference: You'll need to start all the services manually:

bashsudo service start postgres

When you launch the rails server and use your Chrome on Windows it just feels great. The next thing was where to put your Rails project. Initially I opted for /mnt/c/, which is the C:\ harddrive from Windows mounted in Linux. Since I wanted to use Visual Studio code from Windows. This is where the great feeling ended abruptly. Cloning a repository yielded strange errors, and even the suggestions from this GitHub issue didn't help that much. I got it working by adding a wsl.conf in /etc:

bash[automount]
options = "metadata"

But running a simple migration took 2 minutes, and the filesystem access was terribly slow. How slow? Look at Kai Salmens measurements:

Then a friend pointed me to the Microsoft Certified Solution:

Put the project in your Linux home directory (bam migrations took 2 seconds) and edit the source through a Visual Studio Extension called Remote Development.

From then on, the development / feedback loop was ok. Copying files outside Visual Studio is quirky, but you can do it.

Tools that make me happy

I've installed the following tools to enhance my development workflow - most of them are universal to all operating systems, but I share them nonetheless:

  • Hain - as a quick launcher for Applications (think of it Alfred for Windows)

  • Windows Terminal - A fairly new Terminal Application (compared to ConEmu) from Microsoft. It's missing a Quake Style Hotkey (it will come in somewhen in late 2020 / early 2021). It's also missing the possibility to zoom in the Font via a hotkey - fun fact: for zooming out there, is a hotkey, and you can zoom using your mousewheel so ¯\_(ツ)_/¯?! I've installed some Powerline Fonts and configured the terminal with this config:

bash"defaults": {
  // Put settings here that you want to apply to all profiles.
  "fontFace": "Cascadia Code PL",
  "fontSize": 12
}
  • powerline-go - A superfast Powerline port written in go. For this one, I'm currently working on a fork that supports rendering a segment that displays the current Ruby version using rbenv. For the setup, I've followed this tutorial.

  • fish - a modern shell that doesn't leave you in the 80s. This is my config.fish:

bash# ssh
if test -z (pgrep ssh-agent)
  eval (ssh-agent -c)
  set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK
  set -Ux SSH_AGENT_PID $SSH_AGENT_PID
  set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK
end

# go
set -xg GOPATH $HOME/development/go

# rbenv
set PATH $HOME/.rbenv/bin $PATH
set PATH $HOME/.rbenv/shims $PATH
set PATH $GOPATH/bin $PATH
rbenv rehash >/dev/null ^&1

# useful aliases
alias be "bundle exec"
alias ll "ls -laoh"
alias rc "bundle exec rails c"
alias rs "bundle exec rails s"
alias server "python -c 'import SimpleHTTPServer;SimpleHTTPServer.test()'"
  • fnm - Node version manager

  • rbenv - Ruby version manager

  • conda - Python version manager

  • git - Git is usually not worth mentioning, but since most Windows based git clients can't access WSLs file system, you'll work with either Visual Studios git integration or the command line. For the latter I'm providing an excerpt from my .gitconfig:

bash[alias]
        ci = commit
        co = checkout
        st = status
        br = branch
        lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset' --abbrev-commit
        stash-all = stash save --include-untracked
        undo = reset --soft HEAD^
        prune = fetch --prune
        graph = log --graph --all '--pretty=format:%Cred%h%Creset %ad | [%C(bold blue)%an%Creset] %Cgreen%d%Creset %s' --date=iso
[branch]
        autosetuprebase = always
[core]
        excludesfile = ~/.gitignore
        quotepath = off
        precomposeunicode = true
[push]
        default = simple
[rebase]
        autosquash = true
[merge]
        ff = false
        tool = code

Daily work

When you get used to the keyboard layout and know how to avoid some weird accessibility features that pop up on certain keyboard combinations, the developing experience is quite smooth. Windows feels a bit faster than OSX but also less polished. In a multi-monitor setup I had really bizarre resolution bugs with some apps like this one:

A picture of two windows on a screen. The left window has large controls in the topbar, the right one has controls that are about a fourth the size of the left one.
Look at that close button! Please decide on a resolution. KTHXBAI!

But as I said: Visual Studio works at its best. WSL2 is Linux - so you're running a Linux and a Windows is a quite appealing Operating System. Especially  after work when you want to play a game and just double click the icon, and it runs at 60FPS with decent settings. Which brings me to the next topic:

Machine Learning

Since my Notebook has a decent NVIDIA graphic card, I was interested in trying out the machine learning possibilities of WSL2. I followed this tutorial by Michael Phi and installed the complete CUDA, Docker, Tensorflow GPU swag... and it just worked out the box. For so much beta software I've downloaded I was expecting more hurdles. GPU accelerated machine learning on OSX is a pain in the ass. With WSL2, everything is working and it was blazing fast. For the future, this might be a game-changer since I believe that machine learning will get into every facet of software development.

Summary

Will I switch to Windows/WSL2 for development? No! Many things are too quirky in Windowsland (e.g. there is no decent equivalence of TimeMachine for Windows). Will I consider it, when Apple fucks its developer ecosystem with its custom ARM chips? Yes! But there's a point that is much more interesting. In the past, when young students came to 9elements, they always wanted to develop on Windows (they knew it from school and university), but since we've had bad experiences with it, we only allowed OSX and Linux. These times are over! From now on, it's OK to develop on Windows using WSL2, and if Microsoft keeps its direction with Open Source Tools, I promise them a bright future.

I would love to get some feedback on this article, so you should follow me on Twitter and start the discussion. If you have additional tools that are cool but not mentioned in this post, please let me know.

Shameless plug:

Cofounder of 9elements. Software alchemist since he was a kid. Knee deep in tech with building things in React, Rails or Solidity.

Let's talk about