WSL and Ubuntu Web Development Setup
I have been using Windows + WSL2 (Ubuntu) for my web development environment for many years now.
Over time I gathered some helpful resources for setting up such development environment, so I decided
to write this post to have a reference for myself and you, dear reader!
It shows how to set up
- WSL and Ubuntu itself
- git-related tooling
- prerequisites to be able to install, build, etc. codebases using the Node.js ecosystem
- pnpm
- Docker
- VS Code
- and, optionally, additional things
Basic setup for WSL #
-
Open PowerShell as administrator and run:
wsl --install
-
Restart your machine.
-
Run "Ubuntu" from the start menu to start an Ubuntu terminal.
-
It will ask for a username and password - choose some.
-
I like to not having to enter the password when running things in the WSL distribution, do the following to remove it:
-
Run:
sudo visudo
-
At the bottom of the file, add the following line (replace
<username>
with your chosen username):<username> ALL=(ALL) NOPASSWD: ALL
-
Press
CTRL+X
to exit nano and it will prompt you to save. -
Close the terminal and start a new one (by running "Ubuntu" from the start menu).
-
-
Update and upgrade all packages:
sudo apt update && sudo apt upgrade
Ensure reliable network connection for WSL #
Sometimes after I have set up WSL it had strange network issues for outbound connections.
I found some GitHub issues regarding that and one of them mentioned a misconfigured network interface.
That's why nowadays I always do the following one time after setting up WSL (based on ):
-
Start PowerShell as administrator.
-
List the network interfaces of Windows:
netsh interface ipv4 show subinterfaces
-
There should be an interface called
"vEthernet (WSL)"
. Also you must have some WiFi interface, in my case it is called"WiFi"
. Both interfaces should have the same "MTU" value.
If not, run this:netsh interface ipv4 set subinterface "vEthernet (WSL)" mtu=<MTU-value-of-wifi-interface> store=persistent wsl --shutdown
Git and GitHub SSH #
-
Update git to the latest version and add support for git LFS:
sudo apt-get install git sudo apt-get install git-lfs git lfs install
-
Configure git:
git config --global user.name "Your Name" git config --global user.email "your_email@example.com"
-
Create a SSH keypair and add the private key to ssh-agent in Ubuntu (based on ):
# Generate a SSH keypair # When asked for a passphrase, I typically omit that. ssh-keygen -t ed25519 -C "your_email@example.com" -f "~/.ssh/id_rsa_github" # Start the ssh-agent in the background eval "$(ssh-agent -s)" # Add your SSH private key to the ssh-agent ssh-add "~/.ssh/id_rsa_github" # Configure the key for github.com in the SSH config file printf "Host github.com\n IdentityFile ~/.ssh/id_rsa_github" >> ~/.ssh/config # copy the public key into Windows clipboard cat "~/.ssh/id_rsa_github.pub" | clip.exe
-
Add the public key of your new SSH keypair to your GitHub account (note: you must check out the GitHub repositories via SSH then, not via HTTPS):
- Open new SSH key of your GitHub settings
- Title: I recommend to combine the name of your PC with "WSL", like
ZEPHYRUS-M16 WSL
. - Key type: Keep
Authentication Key
- Key: Use the content of the clipboard (= the public key).
Node.js and C/C++ compiler tool chain #
-
Instead of installing Node.js directly I like to use
nvm
to be able to have multiple versions of Node.js installed at the same time (you can read more here: ).
Run this to installnvm
:# replace v0.39.3 by the newest version # you can look it up here: https://github.com/nvm-sh/nvm/releases curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
-
To be able to compile npm packages which include native C++ addons, via
node-gyp
, we need to install a few things:sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev python-is-python3
-
npm has a feature to complete commands via the tab key, so let's enable that:
npm completion >> ~/.bashrc
-
If you want to automatically switch the Node.js version when you enter a directory with a
.nvmrc
file, you can run the code below in bash to add a hook to your.bashrc
:cat >> ~/.bashrc <<- EOM # start: run-nvm-use-if-cwd-has-nvmrc-file # run "nvm use" automatically on directory change if a file ".nvmrc" is present in the new directory (https://stackoverflow.com/a/48322289/1700319) _nvmrc_hook() { if [[ $PWD == $PREV_PWD ]]; then return fi PREV_PWD=$PWD [[ -f ".nvmrc" ]] && nvm use } if ! [[ "${PROMPT_COMMAND:-}" =~ _nvmrc_hook ]]; then PROMPT_COMMAND="_nvmrc_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}" fi # end: run-nvm-use-if-cwd-has-nvmrc-file EOM
pnpm #
-
To just use
p
to runpnpm
, add the following to your.bashrc
:cat >> ~/.bashrc <<- EOM # start: pnpm-alias alias p='pnpm' # end: pnpm-alias EOM
Docker #
Choose one of the following:
- Docker Desktop: This is the recommended option because everything just works.
- Install Docker directly in WSL Ubuntu: Drawbacks are that there is no support for starting containers from Windows directly and multi-platform builds are not possible with this option.
Dockerfile linting via hadolint #
-
# replace v2.10.0 by the newest version # you can look it up here: https://github.com/hadolint/hadolint/releases wget -O /bin/hadolint https://github.com/hadolint/hadolint/releases/download/v2.10.0/hadolint-Linux-x86_64 sudo chmod 777 /usr/bin/hadolint
Docker multi-architecture builds #
Set up a multi-architecture Docker builder for cross-platform builds:
# from https://unix.stackexchange.com/a/748634
docker buildx create --use --platform=linux/arm64,linux/amd64 --name multi-platform-builder
docker buildx inspect --bootstrap
VS Code #
-
Install the extension , then you can run in an Ubuntu terminal
code .
to start VS Code in that folder.I use scripts like below to quickly start development:
alias pkerschbaum_dev='cd ~/workspace/pkerschbaum-homepage && nvm use && code .'
-
To configure VS Code as the tool to edit git commit messages run:
git config --global core.editor "code --wait"
-
Extension Graph is a great tool to visualize the git history.
Additional things #
-
is a great tool to expose a local server to the internet (e.g. to open the web application you work on on your mobile phone).
-
To sync the bash history between terminals, run the following in the Ubuntu terminal to add it to your
.bashrc
:cat >> ~/.bashrc <<- EOM # start: sync-bash-history # sync history between terminals, https://subbass.blogspot.com/2009/10/howto-sync-bash-history-between.html shopt -s histappend PROMPT_COMMAND="history -n; history -a" unset HISTFILESIZE HISTSIZE=2000 # end: sync-bash-history EOM
-
Certain Node.js and Ubuntu combinations can lead to errors when Node.js
crypto
APIs are used. In case you get an error along the lineserror:25066067:DSO support routines:dlfcn_load:could not load the shared library
when running Node.js code you can do this: . -
If there are connection issues (even after fixing the MTU value of the WSL network interface, what we did above) you might need to change the DNS server: .
-
Some WSL tips:
- Run
explorer.exe .
in an Ubuntu terminal to open the Windows Explorer at that directory path. - Run
echo "hello world" | clip.exe
to copy "hello world" to the Windows clipboard. - Run
wsl --shutdown
in Windows CMD or PowerShell to shutdown the WSL instance.
- Run
-
Some Windows tools:
- for screenshots.
- PowerToys for various tools like a window manager and a color picker.
- for creating screen
recordings (supports creating
.mkv
videos, despite its name).