<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James McDonald</title>
    <description>The latest articles on DEV Community by James McDonald (@jmcscript).</description>
    <link>https://dev.to/jmcscript</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F737428%2Ff7127b46-cd58-4b37-a783-7ed506f076b7.jpg</url>
      <title>DEV Community: James McDonald</title>
      <link>https://dev.to/jmcscript</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jmcscript"/>
    <language>en</language>
    <item>
      <title>LAMP Development Using Windows Subsystem for Linux (WSL)</title>
      <dc:creator>James McDonald</dc:creator>
      <pubDate>Sun, 15 Jun 2025 19:12:11 +0000</pubDate>
      <link>https://dev.to/jmcscript/lamp-development-using-windows-subsystem-for-linux-wsl-43pp</link>
      <guid>https://dev.to/jmcscript/lamp-development-using-windows-subsystem-for-linux-wsl-43pp</guid>
      <description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/about" rel="noopener noreferrer"&gt;WSL&lt;/a&gt; provides a convenient Linux file system that runs &lt;em&gt;alongside&lt;/em&gt; Windows. Command-line tools and apps are then available across file systems. This allows you to avoid the pitfalls of dual-booting or running a more resource-intensive virtual machine.&lt;/p&gt;

&lt;p&gt;Considering these benefits, let's set up a development environment for the &lt;a href="https://cloud.google.com/mysql/lamp" rel="noopener noreferrer"&gt;LAMP&lt;/a&gt; stack (&lt;a href="https://en.wikipedia.org/wiki/Linux" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;, &lt;a href="https://cwiki.apache.org/confluence/display/httpd/FAQ#FAQ-WhatisApache?" rel="noopener noreferrer"&gt;Apache&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/8.4/en/what-is-mysql.html" rel="noopener noreferrer"&gt;MySQL&lt;/a&gt;, and &lt;a href="https://www.php.net/manual/en/introduction.php" rel="noopener noreferrer"&gt;PHP&lt;/a&gt;)!&lt;/p&gt;

&lt;p&gt;In this article, we cover these topics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up Windows Subsystem for Linux (WSL)&lt;/li&gt;
&lt;li&gt;Set up Apache&lt;/li&gt;
&lt;li&gt;Set up PHP&lt;/li&gt;
&lt;li&gt;Set up MySQL&lt;/li&gt;
&lt;li&gt;Put it all together&lt;/li&gt;
&lt;/ol&gt;




&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;😕 TL&amp;amp;DR;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;I understand if you're not interested. Feel free to skip the heavy reading and run the automation script I created!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  1️⃣ Set up Windows Subsystem for Linux (WSL) &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;By default, WSL is not enabled on Windows 10 or Windows 11. Without it, we don't have Linux.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install WSL
&lt;/h3&gt;

&lt;p&gt;Open &lt;a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd" rel="noopener noreferrer"&gt;&lt;strong&gt;Command Prompt&lt;/strong&gt; (cmd.exe)&lt;/a&gt; or &lt;a href="https://learn.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7.5" rel="noopener noreferrer"&gt;&lt;strong&gt;PowerShell&lt;/strong&gt; (pwsh.exe)&lt;/a&gt; and install the default distribution. Windows will ask for permission to run this command (choose Yes). Enter your desired credentials when prompted. After the &lt;a href="https://ubuntu.com/about" rel="noopener noreferrer"&gt;Ubuntu&lt;/a&gt; shell appears, keep it open to continue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--install&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folxc76gx6b2dnwfw33pu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folxc76gx6b2dnwfw33pu.gif" alt="WSL is installed along with the default Ubuntu distribution. The user is prompted to set a name and password." width="760" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the installed packages.
&lt;/h3&gt;

&lt;p&gt;Pre-installed packages for any Linux distribution are not consistently up-to-date. On your first run, update before doing anything else. With Ubuntu (24.04 as of writing), the built-in package manager is &lt;a href="https://manpages.ubuntu.com/manpages/jammy/man8/apt.8.html" rel="noopener noreferrer"&gt;apt&lt;/a&gt;. While using the &lt;a href="https://www.geeksforgeeks.org/linux-unix/sudo-command-in-linux-with-examples/" rel="noopener noreferrer"&gt;sudo&lt;/a&gt; command (usually for the first time in a session), enter your password when prompted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femjyeglf0gtnptt5rrk7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femjyeglf0gtnptt5rrk7.gif" alt="The apt package manager is updated, and any outdated packages are upgraded." width="720" height="518"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Set up Apache &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install and enable Apache.
&lt;/h3&gt;

&lt;p&gt;Apache is an &lt;a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Howto/Web_mechanics/What_is_a_web_server" rel="noopener noreferrer"&gt;HTTP server&lt;/a&gt;—it responds to web requests. We need it to get started. After running these commands, press &lt;code&gt;CTRL+C&lt;/code&gt; to return to the Ubuntu shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apache2 &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4ufw4wzk8wpq3gk21hc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4ufw4wzk8wpq3gk21hc.gif" alt="The apache2 service is installed, and the status shows it is enabled." width="720" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the web server.
&lt;/h3&gt;

&lt;p&gt;Apache creates a template home page that you can view in the browser or even with the &lt;a href="https://curl.se/docs/manpage.html" rel="noopener noreferrer"&gt;curl&lt;/a&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7agi9wim9wt4zxmsuh9i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7agi9wim9wt4zxmsuh9i.gif" alt="Running the curl command writes the response HTML in the console." width="950" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a new default directory.
&lt;/h3&gt;

&lt;p&gt;Instead of reconfiguring the default content in the &lt;code&gt;html&lt;/code&gt; directory, create a new root directory (&lt;code&gt;public_html&lt;/code&gt;) to serve from. Ensure that the new directory has specific ownership and permissions. Validate success by checking the contents of the &lt;code&gt;/var/www/&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 2755 /var/www/public_html/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;:&lt;span class="nv"&gt;$USER&lt;/span&gt; /var/www/public_html/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
ll /var/www/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvpqixvrsdmerhjdduyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvpqixvrsdmerhjdduyb.png" alt="A new public_html directory is created with appropriate permissions and ownership." width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Back up the default &lt;em&gt;sites-available&lt;/em&gt; configuration file.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;sites-available.conf&lt;/strong&gt; is the default file that sets your root directory for Apache. Back up a copy in case you run into problems customizing it. Validate success by listing the contents of the &lt;code&gt;/etc/apache2/sites-available/&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/apache2/sites-available/000-default.conf &lt;span class="se"&gt;\&lt;/span&gt;
/etc/apache2/sites-available/000-default-backup.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
ll /etc/apache2/sites-available/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9nposkfxb062dinnbet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9nposkfxb062dinnbet.png" alt="The default file is copied and the process verfied by listing the directory contents." width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Remap to the new default directory.
&lt;/h3&gt;

&lt;p&gt;Change the &lt;strong&gt;DocumentRoot&lt;/strong&gt; to point to our newly created &lt;code&gt;public-html&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;--in-place&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;'s/DocumentRoot.*\/html/DocumentRoot \/var\/www\/public_html/'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
/etc/apache2/sites-available/000-default.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; /etc/apache2/sites-available/000-default.conf &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--regexp&lt;/span&gt; &lt;span class="s1"&gt;'DocumentRoot.*html'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41o0mlxl22n02y6zx40w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41o0mlxl22n02y6zx40w.png" alt="The sed command modifies the DocumentRoot and the grep command confirms the change." width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Set up PHP &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install and verify PHP.
&lt;/h3&gt;

&lt;p&gt;PHP is a server-side scripting language that allows us to render data without burdening the client's device or exposing the code itself. Soon, we'll use it to reveal information from a MySQL service. Here, we'll install the necessary packages and confirm the version of PHP we get.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php libapache2-mod-php php-mysql &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
php &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy90o93f4rz6k5wha18u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy90o93f4rz6k5wha18u.gif" alt="PHP and other required packages are installed. Then the PHP version is displayed." width="720" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test a new home page.
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;index.php&lt;/code&gt; to the default web directory and write the page content using &lt;code&gt;phpinfo()&lt;/code&gt;. Test the results using &lt;code&gt;curl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;?php phpinfo(); ?&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
/var/www/public_html/index.php &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
curl localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxre9dwsujpok07irzzf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxre9dwsujpok07irzzf.gif" alt="A new index.php homepage is created that runs the phpinfo command. curl is used to read the result." width="950" height="684"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Set up MySQL &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install and enable MySQL.
&lt;/h3&gt;

&lt;p&gt;MySQL is an open-source database management system that you can use to start storing data for your website. Whether you are manipulating data using management software, the command line, or interactive web pages, the MySQL service must be running. After running these commands, press &lt;code&gt;CTRL+C&lt;/code&gt; to return to the Ubuntu shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mysql-server &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73tpu8o1o3xcaxfm4ziu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73tpu8o1o3xcaxfm4ziu.gif" alt="The mysql service is installed, and the status shows it is enabled." width="760" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect to MySQL as root and create a new user.
&lt;/h3&gt;

&lt;p&gt;The root user is available by default, but it's likely better to create an alternate user. You'll struggle to connect with MySQL Workbench if you don't complete this step.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;⚠️ Important!&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Each of these three commands must be run separately. Please don't copy and paste this entire block. Also, replace 'username' and 'password' with your Linux credentials.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql
CREATE USER &lt;span class="s1"&gt;'username'&lt;/span&gt;@&lt;span class="s1"&gt;'localhost'&lt;/span&gt; IDENTIFIED BY &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpx0lw1rggrlheytxfzri.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpx0lw1rggrlheytxfzri.gif" alt="The mysql command line is opened and a new user created." width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect to MySQL with your new username and password.
&lt;/h3&gt;

&lt;p&gt;If you make any mistakes, your new user won't get far. So, test it by logging in after running &lt;code&gt;mysql -p&lt;/code&gt; from the bash prompt and then entering your password. When you're finished, return to the Ubuntu shell with the &lt;code&gt;exit&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q2n8bu27md7jfmm9zsj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q2n8bu27md7jfmm9zsj.gif" alt="The mysql command line is opened using the currently logged in user and password." width="950" height="684"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Put it all together &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;To get an idea of what you've accomplished, let's modify the &lt;code&gt;index.php&lt;/code&gt; homepage to get data from MySQL and display it. &lt;/p&gt;

&lt;h3&gt;
  
  
  Open index.php for editing.
&lt;/h3&gt;

&lt;p&gt;First, open the file using the &lt;code&gt;nano&lt;/code&gt; text editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /var/www/public_html/index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a PHP page that connects to a MySQL database.
&lt;/h3&gt;

&lt;p&gt;Replace the current contents of the file with this code (&lt;code&gt;CTRL+V&lt;/code&gt; works). Again, change the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; accordingly. Then, press &lt;code&gt;CTRL+S&lt;/code&gt; to save and &lt;code&gt;CTRL+X&lt;/code&gt; to return to the Ubuntu shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;MySQLi Test&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$mysqli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;mysqli&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;p&amp;gt;MySQLi connected &amp;lt;strong&amp;gt;successfully&amp;lt;/strong&amp;gt;.&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_errno&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connect failed: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SHOW DATABASES"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;p&amp;gt;"&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"SHOW DATABASES result set has &amp;lt;strong&amp;gt;%d rows&amp;lt;/strong&amp;gt;."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;num_rows&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;errno&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Query failed: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;h2&amp;gt;Databases:&amp;lt;/h2&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;ul&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fetch_assoc&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;li&amp;gt;"&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Database"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;/li&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;/ul&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;free&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$mysqli&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify your work.
&lt;/h3&gt;

&lt;p&gt;For the grand finale, why not just open &lt;a href="http://localhost" rel="noopener noreferrer"&gt;localhost&lt;/a&gt; in your browser? You should see output like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvwmuhocz4kxbp1k74dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvwmuhocz4kxbp1k74dx.png" alt="The index.php serves information from MySQL to the browser." width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ TL;DR &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;If you couldn't be bothered to read the article, let's do things the fast way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install WSL
&lt;/h3&gt;

&lt;p&gt;Open &lt;strong&gt;Command Prompt&lt;/strong&gt; (cmd.exe) or &lt;strong&gt;PowerShell&lt;/strong&gt; (pwsh.exe) and install the default distribution. When prompted, enter your desired Linux username and password. Leave Ubuntu open after installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--install&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Auto-configure a LAMP environment
&lt;/h3&gt;

&lt;p&gt;From the Ubuntu console, run this automation script, and enter credentials when prompted.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;⚠️ Warning!&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Running shell (.sh) scripts provided by a strange website can be a terrible idea. So that you know what I'm up to, feel free to visit the publicly available &lt;a href="https://gist.github.com/jmcscript/0efa75b59c21524abf0e539a067a5880" rel="noopener noreferrer"&gt;GitHub Gist file&lt;/a&gt; to see what is happening. Only run it if you trust it!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl https://gist.githubusercontent.com/jmcscript/0efa75b59c21524abf0e539a067a5880/raw/09e9cb7da8756026c94157d9a92e800ffc5bf11a/wsl-setup.sh&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🏁 Conclusion &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;WSL provides an actual Linux-like environment for local development. There are many benefits to this approach. I hope this article helped you get up and running quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does this work for you?
&lt;/h3&gt;

&lt;p&gt;Have you encountered any problems or errors with anything I've had you try? Feel free to contact me or comment on the article. Any feedback is greatly appreciated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use VS Code with WSL
&lt;/h3&gt;

&lt;p&gt;VS Code has a &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl" rel="noopener noreferrer"&gt;WSL extension&lt;/a&gt;. You don't need to code in Linux directly using apt packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use MySQL Workbench with WSL
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.mysql.com/products/workbench/" rel="noopener noreferrer"&gt;MySQL Workbench&lt;/a&gt; is a free visual tool for working with databases. Use it to &lt;a href="http://dev.mysql.com/doc/workbench/en/wb-mysql-connections.html" rel="noopener noreferrer"&gt;connect directly&lt;/a&gt; with WSL when the &lt;code&gt;mysql&lt;/code&gt; service is running by connecting to &lt;code&gt;localhost&lt;/code&gt; with your new user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Docker Desktop with WSL
&lt;/h3&gt;

&lt;p&gt;It seems containers are &lt;em&gt;hot&lt;/em&gt; right now. Using &lt;a href="https://docs.docker.com/desktop/features/wsl/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt;, you can develop locally using WSL and deploy to a production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Article Reference
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/setup/environment" rel="noopener noreferrer"&gt;Set up a WSL development environment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-database" rel="noopener noreferrer"&gt;Get started with databases on Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Command Reference
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://manpages.ubuntu.com/manpages/focal/man1/sed.1.html" rel="noopener noreferrer"&gt;sed&lt;/a&gt; - &lt;a href="https://manpages.ubuntu.com/manpages/jammy/man1/systemctl.1.html" rel="noopener noreferrer"&gt;systemctl&lt;/a&gt; - &lt;a href="https://manpages.ubuntu.com/manpages/trusty/man2/mkdir.2.html" rel="noopener noreferrer"&gt;mkdir &lt;/a&gt;- &lt;a href="https://manpages.ubuntu.com/manpages/xenial/man1/chown.1.html" rel="noopener noreferrer"&gt;chown&lt;/a&gt; - &lt;a href="https://manpages.ubuntu.com/manpages/jammy/man1/cp.1.html" rel="noopener noreferrer"&gt;cp&lt;/a&gt; - &lt;a href="https://manpages.ubuntu.com/manpages/xenial/man1/ls.1.html" rel="noopener noreferrer"&gt;ll&lt;/a&gt; - &lt;a href="https://manpages.ubuntu.com/manpages/focal/man1/grep.1.html" rel="noopener noreferrer"&gt;grep&lt;/a&gt; - &lt;a href="https://www.geeksforgeeks.org/linux-unix/input-output-redirection-in-linux/" rel="noopener noreferrer"&gt;output redirect (&amp;gt;)&lt;/a&gt; - &lt;a href="https://www.php.net/manual/en/features.commandline.options.php" rel="noopener noreferrer"&gt;php&lt;/a&gt; - &lt;a href="https://dev.mysql.com/doc/refman/8.4/en/mysql.html" rel="noopener noreferrer"&gt;mysql&lt;/a&gt; - &lt;a href="https://dev.mysql.com/doc/refman/8.4/en/create-user.html" rel="noopener noreferrer"&gt;CREATE USER&lt;/a&gt; - &lt;a href="https://help.ubuntu.com/community/Nano" rel="noopener noreferrer"&gt;nano&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Related Topics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/about" rel="noopener noreferrer"&gt;What is Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/faq" rel="noopener noreferrer"&gt;Frequently Asked Questions about Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/basic-commands" rel="noopener noreferrer"&gt;Basic commands for WSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/windows/wsl/" rel="noopener noreferrer"&gt;Windows Subsystem for Linux Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode?source=recommendations" rel="noopener noreferrer"&gt;Get started using Visual Studio Code with Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/terminal/" rel="noopener noreferrer"&gt;What is Windows Terminal?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>apache</category>
      <category>php</category>
      <category>mysql</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
