WSL2-Windows Linux Subsystem: A guide to install a Local Web Server Ubuntu-20.04 Apache,PHP8 y MySQL8
Tags: webdev, php, mysql, wsl2
Published: 2021-01-17 23:57:02



#¡¡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](https://i.imgur.com/WjbjvTE.png "Task Manager")

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](https://i.imgur.com/HZJbyue.png
 "Windows Version")

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](https://i.imgur.com/7iYwdwk.png "Windows Features")

**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](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)

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](https://i.imgur.com/h3sRH71.png "Linux Console")

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](https://i.imgur.com/owcbhGW.png "Windows File Explorer")

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
```
Add (copy and paste) the "command lines" that are below.

**===============&nbsp;C O M M A N D S&nbsp;&nbsp;L I N E S&nbsp;==========**
```
#!/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
```
**=======&nbsp;E N D&nbsp;&nbsp;O F&nbsp;&nbsp;T H E&nbsp;&nbsp;C O M M A N D S&nbsp;&nbsp;L I N E S&nbsp;&nbsp;=======**

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
```
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
```

## 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
```
Add these lines to the end of the file:
```
# xfce
startxfce
```
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](https://i.imgur.com/NKWJIga.png "Windows Remote Desktop Connection")

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](https://i.imgur.com/0WWt05Y.png "Gui access to wsl2")

## 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
```
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
```
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](https://i.imgur.com/G8P2PyE.jpg "Access from a smartphone")

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