Microsoft Windows is a popular operating system. With Windows 10 comes a new feature named WSL (Windows Subsystem for Linux). It’s an optional feature that allows developers and advanced users to run a GNU/Linux environment directly on Windows, without the need for traditional virtualization or a dual boot configuration.

In this guide, check out how to start Debian GUI in Windows 10 with WSL.

Debian on WSL

The WSL tool was originally developed by Microsoft in collaboration with Canonical, the creator of Ubuntu. It’s basically a kernel compatibility layer based on Ubuntu.

In 2020, Microsoft released WSL 2. It brings several crucial improvements over WSL 1. It offers better system compatibility, better VM management, full Linux kernel support, and more. Check out the difference between WSL 1 and WSL 2. Note that WSL 2 is only available for Windows 10 version 2004 build 19041 or higher. Run the following command to verify the version of Windows 10 you’re running.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-1.png" data-lazy- height="607" src="data:image/svg xml,” width=”1098″>

Because WSL was originally based on Ubuntu, it supports Debian by default. Debian for WSL is available from Microsoft Store. However, we’ll demonstrate how to install Debian even without a Microsoft account.

In the case of Windows, all the commands will be run on Windows PowerShell with administrative privilege. It’s the Linux equivalent of running a sudo shell. To start PowerShell with administrative privilege, press “Win X” and select “Windows PowerShell (Admin)”.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-2.png" data-lazy- height="582" src="data:image/svg xml,” width=”273″>

Enabling WSL

Optional features like WSL are not enabled by default. Thankfully, enabling WSL is very simple. Run the following command in PowerShell.

$ dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-3.png" data-lazy- height="358" src="data:image/svg xml,” width=”1102″>

WSL 2 also requires the Virtual Machine Platform feature.

$ dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-4.png" data-lazy- height="258" src="data:image/svg xml,” width=”1101″>

These changes require a system restart to be fully functional.

After rebooting, start PowerShell with admin privilege. Enforce WSL 2 as the default version.

$ wsl –set-default-version 2

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-5.png" data-lazy- height="85" src="data:image/svg xml,” width=”1101″>

Note that if you’re running Windows 10 64-bit version, then you may need to download and install the Linux kernel update package for WSL 2.

Downloading and installing Debian

First, check out all the available distros supported by WSL.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-6.png" data-lazy- height="322" src="data:image/svg xml,” width=”1099″>

Tell WSL to install Debian. Debian is available as an installable package from Microsoft Store.

$ wsl –install -d Debian

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-7.png" data-lazy- height="121" src="data:image/svg xml,” width=”1096″>

It may take a couple of minutes for the process to finish.

Configuring Debian

Debian is now installed. If you installed using WSL, a new shell will automatically pop up. During the first start, Debian shell will ask to create a new user.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-8.png" data-lazy- height="253" src="data:image/svg xml,” width=”1339″>

If you want to access Debian later, use the following WSL command. From this point onwards, I’ll be using Windows Terminal for ease of use.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-9.png" data-lazy- height="479" src="data:image/svg xml,” width=”1113″>

Update the APT cache and upgrade all the packages.

$ sudo apt update && sudo apt upgrade -y

Next, we need to verify if we’re running the latest Debian version. At the time of writing this guide, the latest stable release is Debian 11, codenamed bullseye.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-10.png" data-lazy- height="212" src="data:image/svg xml,” width=”1116″>

In my case, it’s Debian 9 (stretch) where it should be Debian 11 (bullseye). It requires a distro upgrade to get to the latest Debian release.

First, make a backup copy of the sources.list file.

$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-11.png" data-lazy- height="68" src="data:image/svg xml,” width=”1111″>

From the sources.list file, replace all the instances of stretch (Debian 9) to bullseye (Debian 11). This will effectively tell APT to work with packages for Debian 11. Open up sources.list in a text editor and replace all the instances of stretch to bullseye.

$ sudo nano /etc/apt/sources.list

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-12.png" data-lazy- height="581" src="data:image/svg xml,” width=”1188″>

Here’s a sample list of repos for Debian 11 bullseye.

$ deb http://deb.debian.org/debian bullseye main contrib non-free


$ deb http://deb.debian.org/debian bullseye-updates main contrib non-free


$ deb http://security.debian.org/debian-security bullseye-security main contrib non-free

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-13.png" data-lazy- height="588" src="data:image/svg xml,” width=”1174″>

Interested in sed? Check out this mega guide on 50 sed examples.

Now, run the APT update commands again.

$ sudo apt clean && sudo apt update

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-14.png" data-lazy- height="236" src="data:image/svg xml,” width=”1187″>

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-15.png" data-lazy- height="484" src="data:image/svg xml,” width=”1187″>

It will for permission to restart various services during the process. Select “Yes”.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-16.png" data-lazy- height="470" src="data:image/svg xml,” width=”1159″>

We can now safely get rid of the obsolete packages on the system.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-17.png" data-lazy- height="282" src="data:image/svg xml,” width=”1184″>

Restart the Debian session to take the changes into effect. Verify the change.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-18.png" data-lazy- height="260" src="data:image/svg xml,” width=”1180″>

Configuring GUI

The Debian system is fully functional at this point. However, the only way to interact with the system is through command-line interface. There’s no GUI by default to use.

We can circumvent this by implementing VNC. The configuration process is somewhat complicated but very much doable.

Prerequisites

There are a couple of prerequisites to this method. First, ensure that the WSL distro is configured to run with WSL 2.

$ wsl –set-version Debian 2

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-19.png" data-lazy- height="126" src="data:image/svg xml,” width=”1352″>

Installing components

Now, access Debian shell. We need some additional components like curl and wget.

$ sudo apt update && sudo apt install -y curl wget

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-20.png" data-lazy- height="352" src="data:image/svg xml,” width=”1332″>

We’ll be installing tasksel, a super handy tool for managing various desktop and service components. Run the following APT command.

$ sudo apt install tasksel

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-21.png" data-lazy- height="283" src="data:image/svg xml,” width=”1331″>

Run tasksel with sudo privilege.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-22.png" data-lazy- height="636" src="data:image/svg xml,” width=”1304″>

It will show a list of package groups and bundles. Press the spacebar to select/deselect a group. Once you’ve selected the desired ones, select “Ok”.

The tool will download and install all the necessary components. It will take some time.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-23.png" data-lazy- height="470" src="data:image/svg xml,” width=”1309″>

Installing the VNC server

The next step is installing the VNC server. For this purpose, we’ll be installing TigerVNC.

$ sudo apt-get install tigervnc-standalone-server

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-24.png" data-lazy- height="311" src="data:image/svg xml,” width=”1339″>

Installing .NET Runtime

The .NET is a general-purpose framework for building apps for Windows, Linux, and macOS by Microsoft. We need it for the next part of the configuration.

Run the following commands to install .NET Runtime. For further in-depth installation instructions, check out the official .NET installation guide by Microsoft.

$ wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-25.png" data-lazy- height="329" src="data:image/svg xml,” width=”1324″>

$ sudo apt install ./packages-microsoft-prod.deb

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-26.png" data-lazy- height="402" src="data:image/svg xml,” width=”1326″>

$ rm packages-microsoft-prod.deb

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-27.png" data-lazy- height="55" src="data:image/svg xml,” width=”1326″>

$ sudo apt update && sudo apt install apt-transport-https

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-28.png" data-lazy- height="577" src="data:image/svg xml,” width=”1329″>

$ sudo apt update && sudo apt install dotnet-runtime-5.0

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-29.png" data-lazy- height="464" src="data:image/svg xml,” width=”1325″>

Installing systemd-genie

WSL, by itself, is only a barebones Linux framework implementation. Using systemd-genie is the way to give Debian a full-fledged and functional Linux framework. Check out more on systemd-genie.

We’ve already installed its dependency (.NET Runtime). All it’s left is configuring the systemd-genie repo and installing the package. Check out in-depth documentation on systemd-genie installation on Debian.

First, configure the APT repo for systemd-genie.

$ wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-30.png" data-lazy- height="332" src="data:image/svg xml,” width=”1330″>

$ chmod a r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-31.png" data-lazy- height="52" src="data:image/svg xml,” width=”1335″>

$ cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list


$ deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main


$ deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main


$ EOF

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-32.png" data-lazy- height="119" src="data:image/svg xml,” width=”1336″>

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-33.png" data-lazy- height="332" src="data:image/svg xml,” width=”1326″>

Finally, install systemd-genie.

$ sudo apt install systemd-genie

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-34.png" data-lazy- height="352" src="data:image/svg xml,” width=”1338″>

All the necessary tools are installed. Time to configure them to get the expected behavior.

Configuring VNC server password

In the VNC setup, each user will have unique passwords. For full functionality, we need at least three passwords, one for each of the following users.

  • root
  • gdm

First, configure the VNC password for the current user.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-35.png" data-lazy- height="126" src="data:image/svg xml,” width=”1333″>

Next, configure the VNC password for root.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-36.png" data-lazy- height="126" src="data:image/svg xml,” width=”1333″>

Finally, configure the VNC password for GDM. Note that you may skip this step if you didn’t choose to install GNOME desktop environment.

$ sudo -H -u Debian-gdm vncpasswd

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-37.png" data-lazy- height="120" src="data:image/svg xml,” width=”1332″>

Replacing default X by Xvnc

The default function of the display manager is to call X instances for each user session (including the login screen). However, because we’re going to use the VNC server, it’s not going to cut. To work with VNC, Xvnc is the proper candidate.

Next, our goal is to swap X to Xvnc. It requires tweaking the Xorg script that calls Xvnc instead of X/Xorg display service.

Before proceeding, it’s always recommended to make a backup of the existing Xorg script.

$ sudo mv /usr/bin/Xorg /usr/bin/Xorg.old

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-38.png" data-lazy- height="76" src="data:image/svg xml,” width=”1332″>

Now, create a new Xorg script.

$ sudo nano /usr/bin/Xorg.new

Enter the following code.

#!/bin/bash

for arg do


  shift


  case $arg in


    vt*)


      set [email protected] ${arg//vt/tty}


      ;;


    -keeptty)


      ;;


    -novtswitch)


      ;;


    *)


      set [email protected] $arg


      ;;


  esac

done

# display geometry

command=(“https://linuxhint.com/usr/bin/Xvnc” “-geometry” “1366×768” “-PasswordFile” ${HOME:-/root}/.vnc/passwd” [email protected])


systemd-cat -t /usr/bin/Xorg echo “launching Xvnc:” ${command[@]}

exec ${command[@]}

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-39.png" data-lazy- height="694" src="data:image/svg xml,” width=”1324″>

Save the file and close the editor. The file must have correct file permissions to work properly.

$ sudo chmod 0755 /usr/bin/Xorg.new

Create a link to the file to emulate the original Xorg script.

$ sudo ln -sf /usr/bin/Xorg.new /usr/bin/Xorg

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-40.png" data-lazy- height="68" src="data:image/svg xml,” width=”1340″>

Configuring environment variables

We need to tweak some environment variables so that Xorg reads from the user executing the genie command. To do so, we need to tweak the bashrc file of both the root and the current user. Note that bashrc is different than bash_profile.

Open the bashrc of the current user.

Add the following codes at the end of the file.

export XDG_RUNTIME_DIR=/run/user/$UID

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk ‘{print $2; exit;}’):0.0

sudo /etc/init.d/dbus start &> /dev/null

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-41.png" data-lazy- height="696" src="data:image/svg xml,” width=”1322″>

Do the same with the bashrc file of the root user.

export XDG_RUNTIME_DIR=/run/user/$UID

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk ‘{print $2; exit;}’):0.0

sudo /etc/init.d/dbus start &> /dev/null

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-42.png" data-lazy- height="690" src="data:image/svg xml,” width=”1326″>

Finally, reload bashrc for the current user.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-43.png" data-lazy- height="767" src="data:image/svg xml,” width=”1328″>

Launching systemd-genie

Now, systemd is configured to let gdm start automatically and create an instance of X display to the login instance. Because of the configuration, it’ll create Xvnc instances instead. It will start listening from 5900.

The next command will show the message “connecting to systemd” followed by a few errors. The errors are expected. You should land on the login screen.

Voila! You’ve now successfully logged in to GUI-enabled Debian running under WSL 2! All that’s left is connecting to the WSL server through VNC. The following command will report the server IP address.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/How-to-Start-Debian-GUI-in-Windows-10-with-WSL-44.png" data-lazy- height="71" src="data:image/svg xml,” width=”1332″>

To connect to the system, use a VNC client (on port 5900). To log in, use the gdm VNC password. This should land you on the login screen.

Final thoughts

For Windows users, WSL is an excellent way to get used to the world of Linux without having to learn everything from scratch. This guide demonstrates recommended method of installing and configuring Debian 11 with GUI on WSL with the help of a VNC server (TigerVNC).

With a suitable VNC configuration, you can achieve a lot more. Check out this in-depth guide on installing and configuring a VNC server on Debian.

Happy computing!

About the author

<img data-del="avatar" data-lazy-src="https://kirelos.com/wp-content/uploads/2021/09/echo/profile-photo-1-150×150.jpg" height="112" src="data:image/svg xml,” width=”112″>

Sidratul Muntaha

Student of CSE. I love Linux and playing with tech and gadgets. I use both Ubuntu and Linux Mint.