πŸ‘‹ this page is from an old version of my website - it will be updated soon to match. until then, all links should still work. enjoy!

wsl: setup

a documentation of how to get a similar or better setup than me using the windows subsystem for linux (v1) as a development environment.

i run this off my surface pro 7, and so long as I keep the majority of my files located in the win10 filesystem then i've never had any major problems or performance issues.

understanding this tutorial

πŸ’‘ if you have a suggestion for additions/improvements, just lemme know. i'm always looking to further my setup.

wsl

install wsl v1

πŸ’‘ v2 runs better due to it using a real linux kernel rather than a wrapper, but currently can only be installed on the windows insider program.
  1. open powershell as admin and run:
  2. 0
    1 Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    0
    
  3. reboot computer.
  4. download ubuntu from the microsoft store.
  5. Get Ubuntu - Microsoft Store en-AU

    Ubuntu on Windows allows one to use Ubuntu Terminal and run Ubuntu command line utilities including bash, ssh, git, apt and many more. Note that Windows 10 S does not support running this app. Before installing Ubuntu on Windows or before the first run please open the Control Panel, visit Programs and Features' submenu Turn Windows features on or off and select Windows Subsystem for Linux.

    https://www.microsoft.com/en-au/p/ubuntu/9nblggh4msv6

  6. open the ubuntu app. it will complete installation of itself, and prompt you to create a user & password. (this password is what you will need to put in when running a command with sudo).
  7. to ensure everything as up-to-date as possible, run:
  8. 0
    1 sudo apt update -y && sudo apt upgrade -y
    0
    
  9. install missing packages commonly used by build tools:
  10. 0
    1 sudo apt install -y build-essential unzip
    0
    

configure windows terminal

  1. download and install a nerd font to win10 (this is necessary for support of non-ascii glyphs/symbols, e.g. powerline). I personally use CaskaydiaCove Nerd Font (the patched version of Cascadia Code).
  2. Nerd Fonts - Iconic font aggregator, glyphs/icons collection, & fonts patcher

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

    https://www.nerdfonts.com/
  3. download windows terminal from the microsoft store.
  4. Get Windows Terminal (Preview) - Microsoft Store en-AU

    The Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL. Its main features include multiple tabs, Unicode and UTF-8 character support, a GPU accelerated text rendering engine, and custom themes, styles, and configurations.

    https://www.microsoft.com/en-au/p/windows-terminal-preview/9n0dx20hk701
  5. open settings with CTRL + ,. find the profile with a source of Windows.Terminal.Wsl and add the following settings. (<username> refers to the ubuntu user you set up above, <font> should be the font you just installed: e.g. CaskaydiaCove Nerd Font).
  6. 0
    1 "startingDirectory": "\\\\wsl$\\Ubuntu\\home\\<username>",
    2 "fontFace": "<font>",
    0
    
  7. optional: to add a custom background image, add the following to the profile. (<image-source> may be a win10 filepath or a url.)
  8. 0
    1 "background": "#000",
    2 "backgroundImageOpacity": 0.2,
    3 "backgroundImageStretchMode": "uniformToFill",
    4 "backgroundImage": "<image-source>",
    0
    
  9. recommended: add a preferred colour scheme to the schemes array in the general terminal setting, and reference it in your Windows.Terminal.Wsl profile like so:
  10. 0
    1 "colorScheme": "<scheme.name>",
    0
    

    a large repository of colour schemes ported from iTerm2 can be found here:

    Windows Terminal Themes

    Web site created using create-react-app

    https://atomcorp.github.io/themes/
  11. recommended: add custom keybindings to the keybindings array in the general terminal settings. these do not interfere with normal use of the shell / other purposes for those keybindings.
  12. 0
     1 "keybindings": [
     2      {
     3        "command": "copy",
     4        "keys": ["ctrl+c"]
     5      },
     6      {
     7        "command": "paste",
     8        "keys": ["ctrl+v"]
     9      },
    10      {
    11        "command": "newTab",
    12        "keys": ["ctrl+t"]
    13      },
    14      {
    15        "command": "closeTab",
    16        "keys": ["ctrl+w"]
    17      }
    18    ]
    0
    

integration with win10

  1. win10 files can be found in /mnt/c. soft link to your regularly used folders. e.g.
  2. 0
    1 ln -s "/mnt/c/Users/<win10-username>/OneDrive" ~/onedrive
    0
    
  3. if you use vs code, it works very nicely with wsl. download the extension Remote - WSL on the win10 side, and that's it: to open something from ubuntu, just run code <folder/file>. (every now and then running the code command may cause a download/update).
  4. πŸ’‘ as tools like git and runtime environments (python, node.js, etc.) are installed on ubuntu opening vs code in this way will become preferably for most development

mounting drives

  1. to auto-mount external drives, add the following to /etc/fstab (ensuring folders are created).
  2. 0
    1 <drive-letter>: /mnt/<drive-letter> drvfs defaults 0 0
    2 # e.g. for the drive D
    3 sudo mkdir /mnt/d
    4 echo "D: /mnt/d drvfs defaults 0 0" | sudo tee -a /etc/fstab > /dev/null
    0
    
  3. to manually/temporarily mount a drive:
  4. 0
    1 sudo mount -t drvfs <drive-letter>: /mnt/<drive-letter>
    2 # e.g. for the drive D:
    3 sudo mkdir /mnt/d
    4 sudo mount -t drvfs D: /mnt/d
    0
    


fish

❔ highly recommended: a better unix shell built on top of bash.
  1. install.
  2. 0
    1 sudo apt-add-repository ppa:fish-shell/release-3
    2 sudo apt update -y
    3 sudo apt install fish
    0
    
  3. to set fish as the default shell, run the following and then close/reopen the prompt:
  4. 0
    1 chsh -s `which fish`
    0
    
  5. ~/.config/fish/config.fish
  6. 0
    1 # run open <location> to open it in the
    2 # native win10 file explorer
    3 alias open="explorer.exe"
    0
    
  7. optional: to slightly customise the terminal title - this will update it to show as [process] path (e.g. [nano] ~/wip-story.txt): ~/.config/fish/config.fish
  8. 0
    1 # custom title
    2 function fish_title
    3   echo "["(status current-command)"] "
    4   pwd
    5 end
    0
    
  9. optional: to replace the default "welcome to fish" shown on open of a shell - will keep track of how many times you've opened the shell, and will present you with a random word: ~/.config/fish/config.fish
  10. 0
     1 # custom greeting
     2 function fish_greeting
     3   echo (date) >> $HOME/.config/prompt-count.txt
     4   set OPENED (wc -l $HOME/.config/prompt-count.txt | awk '{ print $1 }')
     5   if [ $OPENED = 1 ]
     6     echo "welcome. this is your first recorded opening of fish."
     7   else
     8     echo "aight. you've opened this" $OPENED "times (since" (head -n 1 $HOME/.config/prompt-count.txt)")."
     9   end
    10   echo "it is currently" (tail -1 $HOME/.config/prompt-count.txt)"."
    11   if not [ -e $HOME/.config/words.txt ]
    12     echo -n "> downloading list of 466k+ english words to" $HOME"/.config/words.txt... "
    13     wget -O $HOME/.config/words.txt -q https://raw.githubusercontent.com/dwyl/english-words/master/words.txt
    14     echo "done!"
    15   end
    16   echo "do with this what you will: '"(shuf -n 1 $HOME/.config/words.txt)"'"
    17   echo ""
    18 end
    0
    

theme installation: starship

❔ highly recommended: will take your fish experience to another level (+ just generally looks much nicer).
  1. download and install.
  2. 0
    1 curl -fsSL https://starship.rs/install.sh | bash
    0
    
  3. ~/.config/fish/config.fish
  4. 0
    1 # load the starship theme
    2 starship init fish | source
    0
    
  5. ~/.config/starship.toml
  6. 0
    1 # display single-line
    2 add_newline = false
    3 [line_break]
    4 disabled = true
    5 
    6 # nerd-font preset: copy/paste this from the page linked below
    0
    

    Starship: Cross-Shell Prompt

    Here is a collection of community-submitted configuration presets for Starship. If you have a preset to share, please submit a PR updating this file! 😊 This preset doesn't change anything except for the symbols used for each module. If emojis aren't your thing, this might catch your eye!

    https://starship.rs/presets/#nerd-font-symbols


keys

❔ optional: used for secure communication with external servers (e.g. for ssh-ing to a remote machine or for pushing verified commits to github).
  1. ~/.config/fish/config.fish
  2. 0
     1 # ssh-agent
     2 if [ -z (pgrep ssh-agent) ]
     3   eval (ssh-agent -c) > /dev/null
     4   set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK
     5   set -Ux SSH_AGENT_PID $SSH_AGENT_PID
     6 end
     7 if [ (ssh-add -l) = "The agent has no identities." ]
     8   ssh-add
     9   echo ""
    10 end
    11 
    12 # gpg-agent
    13 set -x GPG_TTY (tty)
    0
    

  3. set up git (with user details).
  4. 0
    1 git config --global user.email "<[email protected]>"
    2 git config --global user.name "<Your Name>"
    0
    
  5. setup ssh (install on remotes with e.g. ssh-copy-id, copying to github settings). commands assume you use the default save location.
  6. 0
    1 ssh-keygen -t rsa -b 4096 -C "<[email protected]>"
    2 ssh-add
    3 # exporting public key - will copy the output to your clipboard
    4 cat ~/.ssh/id_rsa.pub | clip.exe
    5 # checking that verification with github was successful
    6 ssh -T [email protected]
    7 
    8 # to reconfigure an existing git repo to use ssh
    9 git remote set-url origin [email protected]:<user>/<project>.git
    0
    
  7. setup gpg (copy pubkey export to github settings).
  8. 0
    1 # copy the pub key ID when done
    2 gpg --gen-key
    3 # configure git to use the key
    4 git config --global user.signingkey <ID>
    5 git config --global commit.gpgsign true
    6 # exporting public key - will copy the output to your clipboard
    7 gpg --armor --export <ID> | clip.exe
    0
    


n (node.js)

❔ optional: used to manage/run node.js (a javascript runtime).
  1. install n:
  2. 0
    1 curl -L https://git.io/n-install | bash -s -- -q -n
    0
    

    ~/.config/fish/config.fish

    0
    1 # n-install
    2 set -x N_PREFIX $HOME/n
    3 if not contains $N_PREFIX/bin $PATH
    4   set -xa PATH $N_PREFIX/bin
    5 end
    0
    
  3. optional: install yarn:
  4. 0
    1 curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
    2 echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
    3 sudo apt update
    4 sudo apt install --no-install-recommends yarn
    0
    

    ~/.config/fish/config.fish

    0
    1 # yarn
    2 if not contains (yarn global bin) $PATH
    3   set -xa PATH (yarn global bin)
    4 end
    0
    


deno

❔ optional: a secure javascript/typescript runtime.

install:

0
1 curl -fsSL https://deno.land/x/install/install.sh | sh
0

~/.config/fish/config.fish

0
1 set -x DENO_INSTALL $HOME/.deno
2 if not contains $DENO_INSTALL/bin $PATH
3   set -xa PATH $DENO_INSTALL/bin
4 end
0


python

❔ optional: for python language use.
  1. install:
  2. 0
    1 sudo apt install -y python3 python3-pip
    0
    
  3. ~/.config/fish/config.fish
  4. 0
    1 # python
    2 if not contains $HOME/.local/bin $PATH
    3   set -xa PATH $HOME/.local/bin
    4 end
    5 alias py=python3
    6 alias python=python3
    7 alias pip=pip3
    0
    

using pipenv for project environments

  1. install:
  2. 0
    1 pip install --user pipenv
    0
    
  3. usage: to install a pip package in the directory environment:
  4. 0
    1 pipenv install <pkg>
    0
    
  5. usage: to install a requirements.txt collection of pip packages in the directory environment:
  6. 0
    1 pipenv install -r requirements.txt
    0
    
  7. usage: to run a command that has access to pip packages installed in the directory environment:
  8. 0
    1 pipenv run <cmd>
    2 # e.g. pipenv run py main.py
    0
    
  9. usage: to launch a shell with the environment added to path, so all commands have access to packages.
  10. 0
    1 pipenv shell
    0
    


php

❔ optional: for php language use. does not include database setup.
  1. download/install apache2 and php7.
  2. 0
    1 sudo add-apt-repository ppa:ondrej/php
    2 sudo apt update -y
    3 sudo apt install -y php7.1 apache2
    0
    
  3. set up composer (a php package manager).
  4. start apache. defaults to document root being in /var/www/html, accessible via http://localhost/.
  5. 0
    1 sudo service apache2 start
    0
    


docker

❔ optional: for running docker containers. if you don’t know what they are, ignore this bit.
❗ warning: this is only for wsl v1. for v2, try this custom implementation or see if you can get docker's official solution working.
  1. install https://hub.docker.com/editions/community/docker-ce-desktop-windows (on the win10 side).
  2. in the app, enable the setting Expose daemon on tcp://localhost:2375 without TLS.
  3. install docker on the ubuntu side:
  4. 0
     1 # update package lists and install dependencies
     2 sudo apt update -y
     3 sudo apt install -y \
     4     apt-transport-https \
     5     ca-certificates \
     6     curl \
     7     software-properties-common
     8 # add and verify docker's key
     9 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    10 sudo apt-key fingerprint 0EBFCD88
    11 # add stable channel & install
    12 sudo add-apt-repository \
    13    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    14    (lsb_release -cs) \
    15    stable"
    16 sudo apt update -y
    17 sudo apt install -y docker-ce
    18 pip3 install --user docker-compose
    19 # allow user to run docker
    20 sudo usermod -aG docker $USER
    0
    
  5. ~/.config/fish/config.fish
  6. 0
    1 # docker
    2 if not contains $HOME/.local/bin $PATH
    3   set -xa PATH $HOME/.local/bin
    4 end
    5 set -x DOCKER_HOST tcp://localhost:2375
    0
    
  7. create soft link to mount point.
  8. 0
    1 sudo ln -s /mnt/c /c
    0
    
  9. check it works (win10 docker desktop must be running).
  10. 0
    1 docker info
    2 docker-compose --version
    0
    


gui

❔ optional: makes running desktop (or apps) with a graphical user interface possible.
  1. first, install vcxsrv on win10. it will show up as an app called XLaunch.
  2. VcXsrv Windows X Server

    Download VcXsrv Windows X Server for free. Windows X-server based on the xorg git sources (like xming or cygwin's xwin), but compiled with Visual C++ 2012 Express Edition. Source code can also be compiled with VS2008, VS2008 Express Edition and VS2010 Express Edition, although current project and makefile are not fully compatible anymore.

    https://sourceforge.net/projects/vcxsrv/
  3. ~/.config/fish/config.fish
  4. 0
    1 # stream to xserver
    2 set -x DISPLAY :0
    3 set -x LIBGL_ALWAYS_INDIRECT 1
    0
    
  5. run dbus.
  6. 0
    1 sudo apt install dbus-x11
    2 sudo systemd-machine-id-setup
    3 sudo service dbus start
    0
    

example app: webstorm

  1. download and install.
  2. 0
    1 wget [https://download.jetbrains.com/webstorm/WebStorm-2019.3.3.tar.gz](https://download.jetbrains.com/webstorm/WebStorm-2019.3.3.tar.gz)
    2 sudo tar xfz WebStorm-*.tar.gz -C /opt/
    0
    
  3. add shortcut - ~/.oh-my-zsh/custom/init.zsh
  4. 0
    1 # webstorm
    2 alias webstorm="/opt/WebStorm-193.6494.34/bin/webstorm.sh"
    0
    
  5. have the xserver running. if it isn't already, run XLaunch (on win10) with the default configuration (just keep hitting Enter).
  6. launch by running the command webstorm.

xfce4 desktop

❔ not recommended: it's possible, sure. doesn't work all too great, though, and there really isn't any need to. you can launch apps fine without it, and you already have the windows desktop.
❗ warning: a number of desktop environments were attempted - too many errors were encountered, download sizes were massive, or apps just wouldn't open for no identifiable reason. so, xfce4 has been included in this tutorial as the best option known of at the time of its writing.
  1. install.
  2. 0
    1 sudo apt install -y xfce4
    0
    
  3. fix permissions.
  4. 0
    1 sudo chown -R $USER:$USER ~
    0
    
  5. launch. to close: do ALT + F4, then navigate back to the terminal window and do CTRL + C.
  6. 0
    1 sudo service dbus start && /mnt/c/Program\ Files/VcXsrv/vcxsrv.exe -ac -wgl -fullscreen -dpms & startxfce4
    0