setting up PHP, MySQL, and Nginx on WSL2 Ubuntu on Windows

Here’s a complete guide to setting up PHP, MySQL, and Nginx on WSL2 Ubuntu on Windows — and calling it all from Windows.

The architecture is: your code lives in WSL Ubuntu, Nginx serves it on a local port, and you access it from Windows via localhost or a custom hostname.

Let me show the full setup visually first, then walk through each step.Now let’s go step by step.


Step 1 — Install WSL2 + Ubuntu

Open PowerShell as Administrator on Windows:

wsl --install

This installs WSL2 and Ubuntu 22.04 by default. Restart when prompted. Then open Ubuntu from the Start menu and create your Linux username/password.

Verify it’s running WSL2 (not WSL1):

wsl -l -v

Step 2 — Update Ubuntu

Inside the Ubuntu terminal:

sudo apt update && sudo apt upgrade -y

Step 3 — Install Nginx

sudo apt install nginx -y
sudo service nginx start

Test it: open your Windows browser and go to http://localhost — you should see the Nginx welcome page.


Step 4 — Install PHP and PHP-FPM

sudo apt install php php-fpm php-mysql php-cli php-mbstring php-xml php-curl -y

Check the version installed:

php -v

Start PHP-FPM (replace 8.x with your actual version, e.g. 8.3):

sudo service php8.3-fpm start

Step 5 — Install MySQL

sudo apt install mysql-server -y
sudo service mysql start
sudo mysql_secure_installation

Follow the prompts to set a root password and secure the install. Then log in and create a database:

sudo mysql -u root -p
CREATE DATABASE myapp;
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON myapp.* TO 'myuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 6 — Configure Nginx to use PHP-FPM

Create a site config:

sudo nano /etc/nginx/sites-available/myapp

Paste this (adjust php8.3 to your version):

server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}

Enable it and reload:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo service nginx reload

Step 7 — Test PHP is working

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/index.php

Visit http://localhost in your Windows browser — you’ll see the PHP info page.


Step 8 — Auto-start services (important!)

WSL2 doesn’t run systemd by default, so services stop when you close the terminal. Fix this by adding a startup script.

Option A — Enable systemd (Ubuntu 22.04+, recommended):

Edit /etc/wsl.conf:

sudo nano /etc/wsl.conf

Add:

[boot]
systemd=true

Restart WSL: in PowerShell run wsl --shutdown, then reopen Ubuntu. Now you can use:

sudo systemctl enable nginx mysql php8.3-fpm

Option B — Manual start alias (simpler, no restart needed):

Add to your ~/.bashrc:

alias start-stack='sudo service nginx start && sudo service mysql start && sudo service php8.3-fpm start'

Calling from Windows

What you wantHow
Open the siteBrowser → http://localhost
Custom hostnameAdd 127.0.0.1 myapp.local to C:\Windows\System32\drivers\etc\hosts, then use server_name myapp.local; in Nginx
Edit files in VS Codecode /var/www/html from WSL terminal (VS Code Remote WSL extension)
Browse files in ExplorerNavigate to \\wsl$\Ubuntu\var\www\html
Connect MySQL from WindowsUse TablePlus/DBeaver with host 127.0.0.1, port 3306
Run PHP from Windows TerminalOpen a WSL tab and run php script.php

Quick troubleshooting

  • Port 80 already in use → Windows may have IIS running. Disable it in “Turn Windows features on or off”, or change Nginx to listen 8080.
  • Services not running after reboot → Enable systemd (Option A above) or run start-stack alias.
  • Nginx config errors → Always run sudo nginx -t before reloading.
  • MySQL access denied → Make sure you’re connecting with the user you created, not root.