Purpose

The windows operating system has made some significant improvements for developers who live and work with Linux servers or Mac users. WSL levels the playing field and is an excellent option.

The following is a collection of my own personal notes. These instructions have an Oracle slant. Your settings may need to be different. The focus here is some common problems, but not exhaustive. No warranty is assumed or implied. This is just transparent note taking.

Installation

Tested steps below (2026-03)

WSL Install and Update

One line enable and install. Reboot may be required if OS features were enabled.

wsl --install OracleLinux_9_5

If you already have WSL, update the base WSL kernel (keeping up to date)

wsl --update

Note: wsl --install will add the default Ubuntu image. This is not required.

Confirm wsl update

wsl -v

Example:

WSL version: 2.6.3.0
Kernel version: 6.6.87.2-1
WSLg version: 1.0.71
MSRDC version: 1.2.6353
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26200.7623

Distribution

Microsoft Store provides an automatic way to install different images. Search WSL or Oracle and you will find a bunch.

Command line also works. Here will will install Oracle Linux 9.5

wsl --list --online

wsl --install -d OracleLinux_9_5

On download and install, you will be prompted for a username and password. Make note of these as they are required for administration activities. Auto-Login will default to this user when launching WSL.

Confirm installation default from PowerShell noting the *

wsl --list --verbose

Set the default WSL if needed.

wsl --set-default OracleLinux_9_5

Example:

PS C:\Users\tsthilai> wsl --list --verbose
  NAME               STATE           VERSION
* OracleLinux_9_5    Stopped         2
  Ubuntu             Stopped         2

Now the default wsl will open our default distribution

PS C:\Users\tsthilai> wsl
[test@TSTHILAI-X40-J tsthilai]$ cat /etc/oracle-release
Oracle Linux Server release 9.5
[test@TSTHILAI-X40-J tsthilai]$

Networking

The following are some high level tips I have found useful when using VPN and WSL as a terminal for development.

Networking mode

Recommended for transparent usage while on vpn: VirtioPorxy

Pre / Post VPN connection

When connecting or disconnecting from VPN, restart your WSL instances. You may get a WSL message popup from Windows when your connection or proxy change

wsl --shutdown
wsl

Create Utility Scripts

Proxy Settings can change depending on VPN and providers. WSL does a good job of inheriting the proxy settings if they are passed to the OS correctly.

If the proxy settings are NOT works as needed, you can take control of those settings. My recommendation:

proxy_set.sh

#!/bin/bash

export no_proxy=localhost,127.0.0.1,.us.oracle.com,.oraclecorp.com
export http_proxy=http://www-proxy.us.oracle.com:80
export https_proxy=${http_proxy}

# include upper case for maximum coverage
export NO_PROXY=${no_proxy}
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}

export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8

echo "================================"
env | grep -i prox[y]
echo "================================"

proxy_unset.sh

#!/bin/bash

unset https_proxy
unset http_proxy
unset no_proxy
unset HTTPS_PROXY
unset HTTP_PROXY
unset NO_PROXY
echo "================================"
echo " Proxy environment unset"
env | grep -i prox[y]
echo "================================"

Create a test script that will allow you to verify your connectivity quickly. In my case, the PROXY settings that should be automatic from my VPN hosts are not always correct. It also depends on which VPN I use (we have multiple ways to connect). This script will help quickly evaluate if the proxy settings impact your connectivity.

proxy_test.sh

#!/bin/bash

# List of URLs to test
URLS=(
    "https://this-url-will-not-resolve.example"
    "https://www.google.com"
    "https://www.oracle.com"
    "https://myserver.my_company.com"
)

# URL column width
COLW=55

# Function to test connectivity to a URL
# You can adjust the column width in the %-${COLW}s part—make it wider/narrower as needed.
test_url() {
    local url="$1"
    status=
    result=$(curl -k -s -o /dev/null -w "%{http_code}" --max-time 2 "$url") || status=$?
    if [[ "$result" == "000" ]]; then
        if [[ "$status" -eq 6 ]]; then
            printf "%-${COLW}s | %s\n" "$url" "Could not resolve host"
        elif [[ "$status" -eq 28 ]]; then
            printf "%-${COLW}s | %s\n" "$url" "Connection timed out"
        else
            printf "%-${COLW}s | curl error code: %s\n" "$url" "$status"
        fi
    else
        printf "%-${COLW}s | %s\n" "$url" "$result"
    fi
}

echo "====== TESTS ======="

# Header
printf "%-${COLW}s | %s\n" "URL" "RESULT"
printf "%-${COLW}s-+-%s\n" "$(printf '—%.0s' $(seq 1 $COLW))" "$(printf '—%.0s' {1..20})"

# Loop over the URLs
for url in "${URLS[@]}"; do
    test_url "$url"
done

echo ""
echo "====== PROXY SETTINGS ======="

env | grep -i proxy

Customize the URL list to work for your environment.

Note: make the script files executable chmod +x proxy_*.sh

Examples

$ source ~/proxy_set.sh
================================
HTTP_PROXY=http://www-proxy.us.oracle.com:80
https_proxy=http://www-proxy.us.oracle.com:80
http_proxy=http://www-proxy.us.oracle.com:80
no_proxy=localhost,127.0.0.1,.us.oracle.com,.oraclecorp.com
NO_PROXY=localhost,127.0.0.1,.us.oracle.com,.oraclecorp.com
HTTPS_PROXY=http://www-proxy.us.oracle.com:80
================================

$ ~/proxy_test.sh
====== TESTS =======
URL                                                     | RESULT
———————————————————————————————————————————————————————-+-————————————————————
https://this-url-will-not-resolve.example               | Could not resolve host
https://www.google.com                                  | 200
https://www.oracle.com                                  | 200
https://myserver.my_company.com                         | 302

====== PROXY SETTINGS =======
HTTP_PROXY=http://www-proxy.my_company.com:80
https_proxy=http://www-proxy.my_company.com:80
http_proxy=http://www-proxy.my_company.com:80
no_proxy=localhost,127.0.0.1,.my_company.com,.oraclecorp.com
NO_PROXY=localhost,127.0.0.1,.my_company.com,.oraclecorp.com
HTTPS_PROXY=http://www-proxy.my_company.com:80

NODE / NPM

Working with NODE modules is common these days. To see the available versions with your distro

sudo dnf module list nodejs

To change the default, be explicit about the version.

sudo dnf module enable nodejs:24
sudo dnf install nodejs

Installed does not equal the correct version. Verify requirements.

node -v
npm -v

NPM Global Installations

WSL has a little difficulty with NODE and using the “global” installations. WSL is often a single user instance. To overcome the protected directories, a parameter for letting node use a user directory for global installations can be set.

Editor of choice ~/.npmrc

Add the following line using $HOME as the example here. Bash variables such as $HOME do not work in .npmrc files. Entries must be absolute paths.

prefix=/home/<your_user>/.npm-global

Now when npm installs global elements, the write error will be avoided.

Command Line NPM

There is probably a name for it… When more advanced NPM is installed, they expect the commands to be in the path. Because you set a custom global, that directory needs to be in your path.

Add this to your ~/.bashrc or respective environment

export PATH="$HOME/.npm-global/bin:$PATH"

11ty

Using some features of 11ty include running a server on the Linux framework.

Localhost server

11ty has the feature to run a local host web server. When WSL is listening on port 8080, Windows has the ability to “Enable localhost forwarding” to the WSL host. This setting can be confirmed inside the networking settings of the WSL settings GUI.

npx @11ty/eleventy --serve

Issue encounters is that the WSL host will default to IPV6. This can be seen by verifying in a second WSL terminal

ss -ltnp4 | grep 8080
ss -ltnp6 | grep 8080

From WSL - IPV4 fail to resolve

curl http://localhost:8080

From WSL - IPv6 will resolve as expected

curl http://[::]:8080

There is more than one way to solve this issue. My preferred solution is to have WSL as a sub-system that runs using IPV4 only.

This is accomplished by telling WSL networking to ignore IPV6.

Edit your Windows OS file ~/.wslconfig Add the following line

kernelCommandLine=ipv6.disable=1

Then re-start the WSL service and re-test.

Priming the 11ty server

Experimentation has lead to the conclusion that the server is not recognized on the HOST OS until it is touched on the WSL server. A curl command primes the server and allows the HOST OS to recognize it.

curl http://localhost:8080

This issue is not large, easy to work around. A better solution is still to be identified.

File Watching / Polling

When editing files from Windows OS, but running 11ty from WSL, the file watching feature which will automatically re-build the files and update the local host server to see the results. Eleventy relies on chokidar/inotify. On WSL, change events can be missed or limited—especially when your project lives on a Windows-mounted drive (/mnt/c) or you’ve hit inotify limits.

Add the following to your environment before starting 11ty.

export CHOKIDAR_USEPOLLING=1
export CHOKIDAR_INTERVAL=300

Note: Polling costs CPU but is the most robust when editing files from Windows tools.

To test:

  • Have a project file base checked out from source code somewhere on the normal C: drive. In WSL it would be on the /mnt/c/…
  • Start 11ty npx @11ty/eleventy --serve for that project
  • From a new wsl terminal, edit a served file
    • It should re-build automatically and can be seen in the server terminal
  • From Windows, edit the same file
    • If it does not auto-build - the polling is the most likely issue