Install apps on Ubuntu on Wsl2 in Windows 10

Posted on March 13, 2021 in DevOps
Updated: June 18, 2021


This blog is a continuation from Install Docker Desktop on Windows 10 Home - including WSL, where I installed WSL2 on a Windows 10 laptop including openSUSE-Leap-15-1 as default distro in WSL2.

In this blog I want to start using Ubuntu 20.04 and see if it gives an ok experience running Linux on Windows (and using it as a developer PC).

If you have installed WSL2 and a default linux disto and in Visual Studio Code have installed Remote WSL then you should open Remote WSL and be able to see your default distro:
Default distro in WSL2

Install Linux distro

Now I want to use Ubuntu instead. Get Ubuntu 20.04 LTS - Microsoft Store Ubuntu distro on the web
Press Get. This will open Microsoft Store on your PC and yet again press Get. It will download 0.5 GB!
When downloaded it will ask you to Launch or to Pin to start. When you Launch you start installing Ubuntu - you just follow the steps.
Ubuntu distro install

Open CMD in your PC.
Now you can see the Ubuntu running, but not default (*)

# CMD on Win10
wsl -l -v
#   NAME                   STATE           VERSION
# * openSUSE-Leap-15-1     Stopped         2
#   docker-desktop-data    Stopped         2
#   Ubuntu-20.04           Running         2
#   docker-desktop         Stopped         2

# Set Ubunto default
wsl --set-default Ubuntu-20.04

Udate to WSL2

In case WSL Version 2 is not default then you need to download WSL2 update, set WSL2 default and finally change your distro to using WSL2.

Verify that you are not running WSL2:

wsl -l -v
#   NAME            STATE           VERSION
# * Ubuntu-20.04    Stopped         1
# with Linux kernel update package installed
# Update your distro to WSL2
wsl --set-version Ubuntu-20.04 2

# wait a while.....

wsl -l -v
#   NAME            STATE           VERSION
# * Ubuntu-20.04    Stopped         2

Using WSL from VSCode

You can see your WSL distros in VSCode
Ubuntu is now Default distro in WSL2

Next you should right-click the distro and Connect to WSL.
This will open up a new VSCode which is directly connected to your WSL, so you can browse its files, edit the files and run the terminal.

Copying files from Windows to WSL

When using CMD you can copy to WSL home dir

# CMD (in Windows)
rasor@DESKTOP:/mnt/c/Users/rasorwin$ # still in a windows folder!
# copy a file from homedir of windows to homedir of wsl
rasor@DESKTOP:/mnt/c/Users/rasorwin$ cp somewinfile.text ~/somewinfile.text
# Install dos2unix into wsl
sudo apt install dos2unix
# convert the winfile to a unixfile
rasor@DESKTOP:/mnt/c/Users/rasorwin$ dos2unix ~/somewinfile.text ~/someunixfile.text

Install apps into the distro

What's in the box?

Open a terminal. You will be in your home folder ~.

Terminal in WSL2.
Nice - so what's in the box?

# bash
# Do we have curl?
curl --version
# curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3

# Do we have wget?
wget --version
# GNU Wget 1.20.3 built on linux-gnu.

# Do we have git?
git --version
# git version 2.25.1

# update packages
sudo apt update

# Do we have python?
python3 -V
# Python 3.8.5
pip3 -V
# Command 'pip3' not found, but can be installed with:
# sudo apt install python3-pip
sudo apt install python3-pip
pip3 -V
# pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)


A copy-paste tool

  • Used during Git config

Install xClip

# bash
sudo apt-get install xclip


Though git is installed you'll probably want configuraions like SSH access to your github repo.

Optionally add some author info:

# bash
git config --global "Your Name"
git config --global ""
git config --list
# The information you entered is stored in your Git configuration file ~/.gitconfig

If you use 2FA on github, then SSH access with a private key avoids having a Personal Access Token to risk to loose and having to cache. More info on Which remote URL should I use?.
So from VSCode rather like to use SSH access (opposed to HTTPS access).
Since you can just regenerate a new SSH key pair, then you don't have to save your private key for later use.

Warning: You should not give the SSH key a passphrase to avoid trouble in VSCode

# bash
# Check for existing SSH keys
ls -al ~/.ssh
# Are there any you want to reuse?
# ls: cannot access '/home/rasor/.ssh': No such file or directory
mkdir ~/.ssh

# I want to generate a new key pair
cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "" -f id_rsa_youruserid_github
# Generating public/private rsa key pair.
# Enter file in which to save the key (/home/youruserid/.ssh/id_rsa): id_rsa_youruserid_github
# Enter passphrase (empty for no passphrase): 
# Enter same passphrase again: 
# Your identification has been saved in id_rsa_youruserid_github.
# Your public key has been saved in
# The key fingerprint is:
# SHA256:X4uMb123456789012345678901234567rWzWRZD1Szl
# The key's randomart image is:
# +---[RSA 4096]----+

# Avoid error "Can't clone git repo and getting error ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory Host key verification failed"
ssh-keyscan -t rsa >> ~/.ssh/known_hosts
# SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.8
ssh-keyscan -t rsa >> ~/.ssh/known_hosts
ssh-keyscan -t rsa >> ~/.ssh/known_hosts
ssh-keyscan -t rsa >> ~/.ssh/known_hosts

# later on you will put your keys in a keychain - for that you need to install one
sudo apt install keychain
# vExtra info on [keychain...](

Now you are ready to use your keychain.

# bash
cd ~/
touch ~/.bash_profile

In VSCode you can blowse to ~/.bash_profile add your newly generated ssh key to the keychain whenever you open a terminal

# ~/.bash_profile
# Add your SSH key to SSH Agent
eval `keychain --eval --agents ssh id_rsa_youruserid_github`
# Now you don't have to add your SSH key to agent (`ssh-add`) before you commit to github.

Open a new terminal to make it take effect.

Add a new SSH key to your GitHub (bitbucket, gitlab, etc) account

# bash
# verify that keychain in installed
eval `keychain`
# * keychain 2.8.5 ~
# * Starting ssh-agent...

# Copy the contents of the file to your clipboard
xclip -sel clip < ~/.ssh/
# Error: Can't open display: (null)

Hmm - xclip not working in WSL - then instead open the file ~/.ssh/ in VSCode and select-all and copy (ctrl-a ctrl-c).

Finally you need to change urls on your local repos remote origin from HTTPS to SSH

# bash
cd your_local_repo
# Print remote url
git remote -v
# is it using HTTPS?

# Change to SSH (get the SSH url from your remote repo on github)
git remote set-url origin
# or if origin was removed:
git remote add origin
# Print remote url
git remote -v

Troubleshooting github connection:

# bash
git clone
# Cloning into 'REPOSITORY'...
# Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.
# Permission denied (publickey).
# fatal: Could not read from remote repository.

# hmmm - do we have our key in the keychain?
keychain --list
# Could not open a connection to your authentication agent.

# does not seem so.
# Try close VSCode - re-open VSCode and a terminal and retry
keychain --list
#v4096 SHA256:X4uMb123456789012345678901234567rWzWRZD1Szl (RSA)

# Nice - try clone again
git clone
# Cloning into 'REPOSITORY'...
# remote: Enumerating objects: 3, done.
# Receiving objects: 100% (3/3), done.

Now we can clone using the SSH key, then add a file, commit and try to see if you can push, too.

NVM and NodeJs

# bash
# Do we have nvm?
nvm -list
# Nope
curl -o- | bash
# => Appending nvm source string to /home/rasor/.bashrc
# => Appending bash_completion source string to /home/rasor/.bashrc
# internal/modules/cjs/loader.js:796
#     throw err;
#     ^

# Error: Cannot find module '\\wsl$\Ubuntu-20.04\mnt\c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js'
#     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:793:17)
#     at Function.Module._load (internal/modules/cjs/loader.js:686:27)
#     at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
#     at internal/main/run_main_module.js:17:11 {
#   code: 'MODULE_NOT_FOUND',
#   requireStack: []
# }
# => Close and reopen your terminal to start using nvm or run the following to use it now:

# export NVM_DIR="$HOME/.nvm"
# [ -s "$NVM_DIR/" ] && \. "$NVM_DIR/"  # This loads nvm
# [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

# ..... something went wrong - but did it matter? Check if it added a NVM envir key:
printenv NVM_DIR
# /home/rasor/.nvm

# Now start yet a terminal and
nvm -list
#             N/A
# iojs -> N/A (default)
# node -> stable (-> N/A) (default)
# unstable -> N/A (default)

# nice - it is installed. Now install latest Node LTS - see
nvm install 14.16.0
nvm list
# ->     v14.16.0
# default -> 14.16.0 (-> v14.16.0)

Great - now I have a fine start with git, python and nodejs in my Ubuntu box on Windows :-)

The End