DEV Community

Cover image for WSL2-Windows Linux Subsystem: A guide to install a Local Web Server Ubuntu-20.04 Apache,PHP8 y MySQL8
Aitor Solozabal
Aitor Solozabal

Posted on • Updated on

WSL2-Windows Linux Subsystem: A guide to install a Local Web Server Ubuntu-20.04 Apache,PHP8 y MySQL8

¡¡PHP 8 is here!!

It was released on November 26, 2020. It is a major new version, which means that it will introduce some major changes, as well as many new features and performance improvements.

As this installation is for development and not for production, it is logical to use PHP 8.0 instead of PHP 7.4 and to test existing systems and their compatibility with this version, as well as the creation of new applications.

An installation of a Local Web Server in the wsl2 subsystem allows to have a true integrated Linux system with their files accessible from Windows and with Windows applications, in addition to sharing the clipboard to copy and paste between the 2 systems (with Ctrl + C / Ctrl + V) in an easier way than with a kind of type VMWare or VirtualBox virtual machine.

WSL2 is not a graphical Linux environment as provided in the default installation (for now) but as a web server it is not required at any time.

Even so, there are tutorials on the Internet to give you access to WSL2 through a graphical user environment (At the end of the guide, one of those procedures is used to allow user access in a graphical environment).

The server is accessed from the browser in Windows with the url: localhost or 127.0.0.1, but it can also be accessed from any other computer in the Local Area Network knowing the IP assigned to the Windows computer host of the WSL2 subsystem installed on that computer and that it also has an IP that is different from the Windows system (see the procedure at the end of the guide).

PREVIOUS REQUIREMENTS

In the BIOS of the computer, the virtualization option must be enabled, just like when you want to run the virtual machines VMWare and VirtualBOX.

To see what the status of our hardware is, we will open the task manager by pressing the Ctrl + Shift + Esc keys at the same time (simultaneously) or by right-clicking on the taskbar and selecting the task manager option.

Once this is done, we expand the view and go to the Performance tab, where we can see the different views of the hardware installed on our computer and that is where you can see the text Virtualization: Enabled or not.

alt text

If this is not the case, you must start the computer and access the BIOS menu (see the computer manual) to enable this hardware feature.

There are systems that do not have this option available, which makes it impossible to install virtual machines on the system.
Verify that the version of Windows 10 is version 1903 or later by doing the following:
Windows key + R

winver

Then click OK button

alt text

In Windows 10 the Programmer Mode option must be enabled.
For this you have to do the following:
Windows key + I to open the Settings menu.
Then select the option Update and security.
Then select the option For programmers.
Then activate the Programmer Mode option.

ENABLE WSL - OPTION 1

Activate optional Windows 10 features
Go to control panel
Programs and Features option
option enable or disable Windows features
check on Windows Subsystem for Linux
check on Virtual machine platform
check on Hyper-V
check on Windows PowerShell 2.

alt text

Restart Windows 10 system

ENABLE WSL - OPTION 2

Open PowerShell
On the taskbar next to the Windows logo, type PowerShell.
The PowerShell icon will appear. Select the Run as administrator option.

Run the following statement to enable the Windows 10 for Linux subsystem in the PowerShell console:

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

Enabling the Virtual Machine feature:

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

Restart Windows 10 system


Whichever option is used you must do the following afterwards:

In your internet browser download the latest version of the WSL2 linux subsystem with the latest updated kernel:

LAST KERNEL

Execute the installation of the downloaded file by pressing the right mouse button on it and choosing the option to install.


Open PowerShell
With the same procedure as in the previous time.
To set wsl2 as the default linux system by entering and executing the following statement in the PowerShell console:

wsl --set-default-version 2

From the Windows Store look for LINUX and you can choose any ubuntu distro or others.

Now there are 3 Ubuntu distros:
the basic version, version 18.04 LTS and version 20.04 LTS all of them are free.

Choose UBUNTU 20.04 LTS
Get, Install and Start

In the installation define a user "XXXXXXXX" and his password "YYYYYYYY" (minimum 8 characters)

alt text

In the Windows PowerShell console you can check which version of wsl is active and which distro is installed with the command:

wsl --list --verbose

Will appear on the console

NAME STATE VERSION
Ubuntu-20.04 Running 2

See help for wsl commands with :

wsl –help

To uninstall :

wsl --unregister Ubuntu-20.04

To turn off wsl :

wsl –shutdown

There are instructions for exporting a WSL installation made on one computer and importing it on another

=========== I M P O R T A N T ============

To work from the windows file explorer or from any other windows application on the files within the wsl2 subsystem, we must first have the wsl2 subsystem started to avoid corruption problems if those files were accessed.

Always access via \wsl$

The way to start the wsl2 subsystem for the installation of the rest of Ubuntu programs is through the linux root user, for this we must execute, with administrator privileges, in any command console in windows (cmd, PowerShell preferably, windows terminal) and enter the following command:
Set as the default user for now and the following sessions:

ubuntu2004 config --default-user root & ubuntu2004.exe

From now on and later with the wsl.exe command it would also be the root user if that is what you want.

On the other hand, the Linux wsl2 subsystem can be accessed as root or any other user in the session that is opened with the following command:

wsl --user root

The following times, if nothing is indicated, it will be with the user defined by default in the installation.

From that moment we can edit the same file in the Linux subsystem with:
In a Windows console:

notepad.exe \wsl$\Ubuntu-20.04\var\www\html\phpinfo.php

In the Linux wsl2 console:

/mnt/c/Windows/System32/notepad.exe /var/www/html/phpinfo.php

From the windows explorer we can access the windows folders and files as well as the linux folders and files and copy, move, delete, edit between both systems as if they were one.

There may be a problem with the permissions defined in the wsl2 Linux Subsystem that do not allow access to users not logged into the system.

With WSL2, a much more comfortable development environment is created using the Windows tools for code editing and maintenance of the files involved and running on the Linux Ubuntu web server.

Obviously this is also achieved in windows development with other utilities that act as local web servers of type WAMP like xampp, Uniform Server Zero XIV, Local, etc ...

To access the files in the wsl2 UBUNTU distro from the WINDOWS 10 explorer:

Open windows explorer and enter \wsl$

The filesystem of the Ubuntu distro installed in wsl2 appears

alt text

You can copy, delete and edit any file or folder in Ubuntu from Windows using Windows applications.

To access disks, folders and files in Windows from the Ubuntu prompt in WSL2

To access the /mnt folder
Example :

ls /mnt/c

Example :

cd /mnt/e/my_project/

Once Ubuntu is installed in WSL2, it can be started from several places:

  • By clicking on the Ubuntu icon in Windows applications with the Metro Interface (in the start menu if it has been previously arranged)

  • Clicking on the shortcut on the taskbar (if previously arranged)

  • Opening CMD console / Terminal Window / PowerShell in Windows with the wsl.exe command or in Linux root mode as mentioned above with the command:

ubuntu2004 config --default-user root & ubuntu2004.exe

The Ubuntu window will open with the system prompt.

For the installation of the rest of the utilities and applications of the Ubuntu system, we are going to specify and concentrate all the basic and initially automatable in a single batch execution file that will be executable from the "prompt" of the system.

First you have to change to SuperUser mode to have the necessary permissions with the following command:

sudo su

Enter the password "YYYYYYYY" of the user "XXXXXXXX" previously defined at the beginning of the Ubuntu installation.

Then change to the root directory of the system with the command:

cd /

Execute the command "cat" to create the file:

cat <<EOF >runme.sh
Enter fullscreen mode Exit fullscreen mode

Add (copy and paste) the "command lines" that are below.

=============== C O M M A N D S  L I N E S ==========

#!/bin/bash
apt-get update
apt-get upgrade -y
echo "*********************************************************************"
echo "* INSTALLING THE APACHE2 SYSTEM *"
echo "*********************************************************************"
apt install apache2 -y # instalar Apache
service apache2 start # iniciar el servicio Apache
echo "*********************************************************************"
echo "* In Windows 10 go to the browser and enter: localhost *"
echo "* The APACHE home page should appear *"
echo "*********************************************************************"
read -p "End of APACHE2 installation - Press the [Enter] key to continue..."
echo "*********************************************************************"
echo "* INSTALl PHP 8.0 *"
echo "*********************************************************************"
add-apt-repository ppa:ondrej/php # Press enter when prompted.
apt-get update
apt install php8.0-common php8.0-cli -y
apt install php8.0-{bz2,curl,intl,mysql,readline,xml} -y
apt install libapache2-mod-php8.0 -y
service apache2 reload # Reiniciar el servicio Apache
echo "*********************************************************************"
read -p "Finish PHP 8 installation - Press the [Enter] key to continue ...."
echo "*********************************************************************"
echo "* MYSQL SERVER 8.0 INSTALLATION *"
echo "*********************************************************************"
echo "* Enter password: ZZZZZZZZ for MySQL root user *"
echo "*********************************************************************"
apt update
apt upgrade -y
apt install mysql-server -y # instalar MySQL
usermod -d /var/lib/mysql/ mysql
service mysql start # Iniciar el servicio MySQL
echo "*********************************************************************"
read -p " End MySQL 8 installation - Press the [Enter] key to continue... "
echo "*********************************************************************"
echo "* INSTALLING SECURITY IN MYSQL SERVER *"
echo "*********************************************************************"
echo "* Questions during installation of Mysql Security *"
echo "*********************************************************************"
echo "VALIDATE PASSWORD PLUGIN can be used to test passwords"
echo "and improve security. It checks the strength of password"
echo "and allows the users to set only those passwords which are"
echo "secure enough. Would you like to setup VALIDATE PASSWORD plugin?"
echo " "
echo "Press y|Y for Yes, any other key for No: [ N ]"
echo " "
echo "Please set the password for root here."
echo "New password:ZZZZZZZZ"
echo "Re-enter new password:ZZZZZZZZ"
echo "*********************************************************************"
echo "By default, a MySQL installation has an anonymous user,"
echo "allowing anyone to log into MySQL without having to have"
echo "a user account created for them. This is intended only for"
echo "testing, and to make the installation go a bit smoother."
echo "You should remove them before moving into a production"
echo "environment."
echo " "
echo "Remove anonymous users? (y|Y for Yes, any other key for No):[ Y ]"
echo "*********************************************************************"
echo "Normally, root should only be allowed to connect from"
echo "'localhost'. This ensures that someone cannot guess at"
echo "the root password from the network."
echo " "
echo "Disallow root login remotely? (y|Y for Yes, y other key for No):[ N ]"
echo "*********************************************************************"
echo "By default, MySQL comes with a database named 'test' that"
echo "anyone can access. This is also intended only for testing,"
echo "and should be removed before moving into a production"
echo "environment."
echo " "
echo "Remove test database and access? (y|Y for Yes,other key for No):[ N ]"
echo "*********************************************************************"
echo " ... skipping."
echo " Reloading the privilege tables will ensure that all changes"
echo " made so far will take effect immediately."
echo " "
echo " Reload privilege tables now? ( y|Y for Yes, other key for No):[ Y ]"
echo "*********************************************************************"
read -p " Write down the answers (N Y N N Y) and press the [Enter] key..."
echo "*********************************************************************"
mysql_secure_installation # Establecer la seguridad en MySQL
service mysql restart # Reiniciar el servicio MySQL
echo "*********************************************************************"
echo "* ENTER TO MYSQL CONSOLE *"
echo "*********************************************************************"
echo "* Enter password: ZZZZZZZZ for MySQL root user *"
echo "*********************************************************************"
echo " Create a user 'your-user' other than root with all the privileges "
echo " enough both to access from phpmyadmin and connect from a webservice "
echo " To do this, enter the following instructions in the MySQL console "
echo " (copy and paste all together) "
echo "CREATE USER 'your-user' @'%' IDENTIFIED BY 'your-password';"
echo "GRANT ALL PRIVILEGES ON *.* TO 'your-user' @'%' WITH GRANT OPTION;"
echo "FLUSH PRIVILEGES;"
echo "exit; "
echo "*********************************************************************"
mysql -u root -p
service mysql restart
echo "*********************************************************************"
echo "* END OF SECURITY INSTALLATION IN MYSQL SERVER *"
echo "*********************************************************************"
read -p " Press the [Enter] key to continue...."
echo "*********************************************************************"
echo "* INSTALL phpMyAdmin 5.0.4 MySQL Manager *"
echo "*********************************************************************"
read -p " Press the [Enter] key to continue..."
echo "*********************************************************************"
wget https://files.phpmyadmin.net/phpMyAdmin/5.0.4/phpMyAdmin-5.0.4-all-languages.tar.gz
tar xzf phpMyAdmin-5.0.4-all-languages.tar.gz
mkdir /usr/share/phpmyadmin
mv phpMyAdmin-5.0.4-all-languages/* /usr/share/phpmyadmin
rm -rf phpMyAdmin-5.0.4-all-languages
rm phpMyAdmin-5.0.4-all-languages.tar.gz
mkdir /usr/share/phpmyadmin/tmp
chown -R www-data:www-data /usr/share/phpmyadmin
chmod 777 /usr/share/phpmyadmin/tmp
echo "*********************************************************************"
read -p " End of installation phpMyAdmin - Press [Enter] to continue.."
echo "*********************************************************************"
echo "* To finish you must copy and paste all following lines in the console to configure phpMyAdmin *"
echo "*********************************************************************"
echo "cat > /etc/apache2/conf-available/phpmyadmin.conf<<EOF"
echo "Alias /phpmyadmin /usr/share/phpmyadmin"
echo "Alias /phpMyAdmin /usr/share/phpmyadmin"
echo ""
echo "<Directory /usr/share/phpmyadmin/>"
echo " AddDefaultCharset UTF-8"
echo " <IfModule mod_authz_core.c>"
echo " <RequireAny>"
echo " Require all granted"
echo " </RequireAny>"
echo " </IfModule>"
echo "</Directory>"
echo ""
echo "<Directory /usr/share/phpmyadmin/setup/>"
echo " <IfModule mod_authz_core.c>"
echo " <RequireAny>"
echo " Require all granted"
echo " </RequireAny>"
echo " </IfModule>"
echo "</Directory>"
echo "EOF"
"*********************************************************************"
read -p " End of configuration of phpMyAdmin - Press [Enter] to continue.."
echo "*********************************************************************"
echo "*********************************************************************"
echo "* To finish you must copy and paste all following lines in the console to show PHP information *"
echo "*********************************************************************"
echo "cat > /var/www/html/phpinfo.php<<EOF"
echo "<?php phpinfo(); ?>"
echo "EOF"
"*********************************************************************"
read -p " End of PHPinfo.php PHP information - Press [Enter] to continue.."
echo "*********************************************************************"
"*********************************************************************"
echo "* To finish you must copy and paste all following lines"
echo "                       ( ONE-BY-ONE) "
echo "and execute in the console to finish the installation *"
echo "*********************************************************************"
echo "a2enconf phpmyadmin"
echo "service apache2 restart"
echo "service apache2 reload"
echo "php --version"
echo "mysql --version"
echo ""
echo "*********************************************************************"
echo "* END OF THE INSTALLATION OF LAMP APACHE2 WEB SERVER - PHP8 - MYSQL8*"
echo "*********************************************************************"
read -p "Press the [Enter] key to continue..."
echo "*********************************************************************"
echo " Once these lines have been copied and executed in the console "
echo "*********************************************************************"
echo "1.- In Windows 10 in the browser enter: localhost/phpinfo.php "
echo " You will see the PHP features installed "
echo "2.- In Windows 10 in the browser enter: localhost/phpmyadmin"
echo " Enter user: your-user Enter password: your-password "
echo " Create database, tables, define fields, queries, etc.."
EOF
Enter fullscreen mode Exit fullscreen mode

======= E N D  O F  T H E  C O M M A N D S  L I N E S  =======

Make the file executable with:

chmod +x runme.sh

Finalmente ejecutar con:

./runme.sh


When executing this installation file, you should pay attention to the messages that are displayed and answer some related questions.

After execution of the installation of Apache2 / PHP 8.0 / MySQL 8.0 / phpMyAdmin 5.0.4 the Local Web Server is finished, then enter the following instruction to exit SuperUser mode:

exit

Other features

To set the priority of PHP files over HTML files on the Apache server:

sudo nano /etc/apache2/mods-enabled/dir.conf

change:

DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm

with this:

DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm

Restart the Apache server for the changes to be recognized with:

sudo service apache2 restart
sudo service apache2 status

Finally
Exit from mode SuperUser

exit


Then to START the services manually every time wsl2 is started:

sudo service apache2 start
sudo service mysql start

But it is more practical to make these instructions run automatically at startup to activate the services, therefore you have to edit the bashrc file:

sudo nano ~/.bashrc

## Start apache2 if not running
status=`service apache2 status`
if [[ $status == *"apache2 is not running" ]]
then
sudo service apache2 start
fi
## Start MySQL if is stopped
status=`service mysql status`
if [[ $status == *"MySQL is stopped." ]]
then
sudo service mysql start
fi
Enter fullscreen mode Exit fullscreen mode

When starting WSL these services are started asking for the SuperUser password since they are executed with permissions with the SUDO instruction.
Instructions when exiting the system at shutdown by editing the bash_logout file.

sudo nano ~/.bash_logout

## Stop apache2 if running
status=`service apache2 status`
if [[ $status == *"apache2 is running" ]]
then
sudo service apache2 stop
fi
## Stop Mysql if running
status=`service mysql status`
if [[ $status != *"MySQL is stopped." ]]
then
sudo service mysql stop
fi
Enter fullscreen mode Exit fullscreen mode

Enable GUI (graphical environment) for Ubuntu-20.04 LTS in WSL

In the case that you want to access the Linux subsystem in a graphical environment, among many other solutions, is using the Windows 10 Remote Desktop, for which you have to execute ONE BY ONE (copy and paste in the terminal) the following instructions in the Ubuntu installation on WSL2:

sudo apt update && sudo apt -y upgrade
sudo apt-get purge xrdp
sudo apt install -y xrdp
sudo apt install -y xfce
sudo apt install -y xfce4-goodies
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
sudo sed -i "s/3389/3390/g" /etc/xrdp/xrdp.ini
sudo sed -i "s/max_bpp=32/#max_bpp=32\nmax_bpp=128/g" /etc/xrdp/xrdp.ini
sudo sed -i "s/xserverbpp=24/#xserverbpp=24\nxserverbpp=128/g" /etc/xrdp/xrdp.ini
echo xfce4-session > ~/.xsession

Then edit the following file:

sudo nano /etc/xrdp/startwm.sh

Search and find the following lines and put the symbol # at the beginning of the lines:

# test -x /etc/X11/Xsession && exec /etc/X11/Xsession
# exec /bin/sh /etc/X11/Xsession
Enter fullscreen mode Exit fullscreen mode

Add these lines to the end of the file:

# xfce
startxfce
Enter fullscreen mode Exit fullscreen mode

Then Ctrl + O and Ctrl + X to save the changes and exit.

Then write, in the terminal, to initialize the following:

sudo /etc/init.d/xrdp start

Then in Windows in the search field where it says "Type here to search" write Remote Desktop Connection and then click on the open option.

Enter localhost: 3390 and click enter.
Then the user xxxxxxxx and the password yyyyyyyy

Connection to remote desktop

alt text

If you want to automate the remote desktop service startup at the same time when the system starts.

sudo nano ~/.bashrc

Add at the end the line:

sudo /etc/init.d/xrdp start

Then Ctrl + O and Ctrl + X to save the changes and exit.

alt text

Access from any device on the LAN (Local Area Network) to Local Web Sever on wsl2

As a continuation of the procedure for installing a local web server in WSL 2, we will proceed to establish access from any device connected to the local area network, either by cable (PC / laptop) or by Wi-Fi (smartphone / tablet / laptop ) to this server.

Suppose that the host PC / laptop where the web server is installed in the WSL 2 subsystem is connected to the local area network through a Wi-Fi connection.
In a PowerShell or cmd console / terminal and through the ipconfig instruction we see that the IPv4 address of the host in the wireless network is 192.168.1.40

ipconfig
Adaptador de LAN inalámbrica Wi-Fi:
Sufijo DNS específico para la conexión. :
Vínculo: dirección IPv6 local..... : fe80::977:7a5f:1a4d:3b1b%
Dirección IPv4............ .: 192.168.1.40
Máscara de subred.......... .: 255.255.255.
Puerta de enlace predeterminada... .. : 192.168.1.1
Enter fullscreen mode Exit fullscreen mode

Once a PC / Laptop / Tablet / Smartphone connected to the same Wi-Fi network is able to "PING" with a positive response to this previous IP address, we will do the following.

In the Windows system of the "host" computer of the wsl2 subsystem, with a text editor must be created a text file "startup-server-web.ps1" in the directory of the computer you want, but preferably in C:\ with the following instructions (copy & paste):

$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
$ports=@(80,443,10000,3000,5000);
#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -
LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -
LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr
connectport=$port connectaddress=$remoteport";
}
# boot the linux wsl2 subsystem set by default
wsl
Enter fullscreen mode Exit fullscreen mode

From a PowerShell console/terminal opened in administrator mode, execute this file:

.\startup-server-web.ps1

At this time the web server in WSL 2 can be accessed from a device on the same local área network with the instruction in the browser of the host's IP address: 192.168.1.40

alt text

If there is any error in this guide, please comment to be corrected

Top comments (3)

Collapse
 
jensbrak profile image
jensbrak • Edited

Hi. Just registered on this site to express my appreciation for your post here. I had much use for it, since it is very well organized and more importantly thorough and complete. The information is 'out there' for sure - but your take on it is the best I found. It takes you through the whole process - from start to finish - and is very clear and pedagogic. Well done!

A couple of notes connected to your excellent tutorial:

First - On my system, when I tried to, I couldn't install xfce as you described (ie 'sudo apt install -y xfce' ). I had to install it specifying version too (as you do in the line below for the -goodies package): 'sudo apt install -y xfce4'.

Second - I kinda felt too restricted by using the (very good I must say) script, so I used it but manually. Especially since I wanted to specify some versions of the sofware installed. Ended up with a new version of the script which is without the very pedagogic messages but with some variables to set at the start - to specify versions desired. Nothing fancy, but if interested, I'd happy to provide it. I still consider it the work of you so I won't distribute it myself.

Third: there is a couple of packages in Windows Store related to Window Manager for WSL, for instance GWSL. I haven't tried any since I found your approach more comfortable and fun - but maybe worth a mention? If it's usable that is.

Again, thanks for the excellent tutorial!

Collapse
 
linenoize profile image
Linenoize

and line 150. I missed that one.

Collapse
 
linenoize profile image
Linenoize

runme.sh has a couple errors:
line 145 and 157 need to start with "echo "