Grayscale profile picture

Patrique Ouimet

Senior Product Engineer

Setting Up Windows Subsystem for Linux for Laravel Development (LEMP)

Thu, Sep 21, 2017 8:24 PM

Introduction

This is a guide on how to get setup with Windows Subsystem for Linux (Ubuntu) for Laravel Development (LEMP). Which gives you the flexibility of the Linux terminal and the application compatibility of Windows.

Recently I decided to switch from Ubuntu 16.04 to Windows 10 Pro as I wanted access to applications that are not available on Linux based operating systems (i.e. Microsoft Office 2016, Adobe Suite). I know there are plenty of alternatives (or things like Play on Linux, Lutris, Crossover), but I wanted to tests on what my customers are using and I got tired of using virtual machines. All that to say that I’ve got Ubuntu application (Windows Subsystem for Linux) working on Windows 10 Pro, so I didn’t lose any of the power of the Linux terminal but gained all the application compatibility of the Windows 10 operating system.

Caveats

I’m using the Insider Program builds so my current system looks like:

  • Edition: Windows 10 Pro
  • Version: 1709
  • OS Build: 16288.1

Also, I do realize there are other versions of Linux based operating systems you can install from the Windows Store, but for the purpose of this article I will assume you have installed the Ubuntu application.

Update/Upgrade Before Starting the Guide

Before we get into setting up LEMP, let’s make sure Ubuntu is up to date, open the Ubuntu application and run the following:

sudo apt-get update && upgrade

NOTE: ignore any messages relating to rc.update

LEMP (Linux, Nginx, MySQL, PHP)

Nginx

Install Nginx

sudo apt-get install nginx

MySQL

Install MySQL

sudo apt-get install mysql-server

PHP (FPM) with Extensions

sudo apt-get install php-fpm php7.0-zip php-curl php-cli php-mysql php-common php-mbstring php-xml

Tweaking FPM

sudo nano /etc/php/7.0/fpm/php.ini

TIP: Within nano press Ctrl+W then type in "fix_pathinfo=1" then press Enter, should bring you right to the line to change. Once the editor (nano) is open, find and uncomment the line with cgi.fix_pathinfo and set the value to

cgi.fix_pathinfo=0

Setting up Git

sudo apt-get update
sudo apt-get install git

Setting up Composer

curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

Setting up Laravel Valet (Linux)

We'll need to install a few dependencies Valet Linux has

sudo apt-get update
sudo apt-get install network-manager libnss3-tools jq xsel

Then install the package globally via composer

composer global require cpriego/valet-linux

Now add composer's vendor bin to the bottom of your .bashrc

export PATH="$PATH:$HOME/.composer/vendor/bin"

Source you're .bashrc

source ~/.bashrc

Now install dnsmasq

sudo apt-get install dnsmasq

Create a directory for it within your /etc/NetworkManager directory

sudo mkdir /etc/NetworkManager/dnsmasq.d

Now install Valet

valet install

Fixing issues with DNS, FPM, and Nginx

First let's fix Nginx, you'll need to edit /etc/nginx/sites-available/valet.conf, update the line that contains fastcgi_pass to:

fastcgi_pass 127.0.0.1:9000;

We'll do the same for FPM, edit /etc/php/7.0/fpm/pool.d/valet.conf, update the line that contains listen = /home/{user}/.valet/valet.sock; to:

listen = 127.0.0.1:9000;

Valet's routing uses wildcards within the hosts file *.dev so you can visit your projects at your project name with the top level domain dev (i.e. my-project.dev). Unfortunately Windows hosts file doesn't allow us to do this, so I've opted to use: Acrylic DNS Proxy

Once you install Acrylic DNS Proxy, open your start menu and search for "Edit Acrylic Hosts File" then click it. Scroll to the bottom of the file comment out the existing entries and add 127.0.0.1 *.dev, the end of your file should look something like this:

# 127.0.0.1 localhost localhost.localdomain
# ::1 localhost localhost.localdomain
127.0.0.1 *.dev

We need to update our network adapters DNS server IP address to use Acrylic's (localhost).

Do the following steps:

  1. Open Control Panel
  2. Click "Network and Internet"
  3. Click "Network and Sharing Center"
  4. Click "Change adapter settings"
  5. Right click on your internet adapter
  6. Click "Properties"
  7. Click on "Internet Protocol Version 4 (TCP/IPv4)"
  8. Click "Properties"
  9. Click "Use the following DNS server addresses"
  10. Add "127.0.0.1" to "Preferred DNS Server"
  11. Run a program call "Purge Acrylic Cache Data", say yes to all the prompts
  12. Open Command Prompt and run "ipconfig /flushdns"

Automating Starting of Services

WSL doesn't start services on start up, so we'll add a script to do it. Here's a simple start services script I've create ~/lemp-start.sh:

#!/bin/bash

if ps ax | grep -v grep | grep 'php-fpm' > /dev/null
then
    echo 'FPM is running'
else
    sudo service php7.0-fpm start
fi

if ps ax | grep -v grep | grep 'nginx' > /dev/null
then
    echo 'Nginx is running'
else
   sudo service nginx start
fi

if ps ax | grep -v grep | grep 'mysql' > /dev/null
then
    echo 'MySQL is running'
else
    sudo service mysql start
fi

To have this run when you open the Ubuntu application we have to add it your ~/.bashrc file:

~/lemp-start.sh

Now close your Ubuntu applications and reopen it. You'll be prompted for your sudo password and should see the services starting.

A Note on Project Directories

DO NOT place your projects (or root valet directory) within the Ubuntu file system. My suggestion would be to place it on the C drive. In example, I place all my code here (where {USERNAME} is your Windows user name):

/mnt/c/Users/{USERNAME}/code

So if you had a project named test it would live in /mnt/c/Users/{USERNAME}/code/test.

If you're curious why not to have files on the Ubuntu file system, have a look here.

Valet Link, Let's See it in Action!

Now that everything is in place, let's test it!

Let's try a new laravel project (remember {USERNAME} is your Windows user name)

cd /mnt/c/Users/{USERNAME}/code
composer create-project --prefer-dist laravel/laravel blog

Once the install is complete, link the directory with Valet:

cd /mnt/c/Users/{USERNAME}/code/blog
valet link

And visit blog.dev in your browser.

Extras

At the time of writing this post systemctl (for systemd) command outputs an error but service command still works:

sudo systemctl status nginx
Failed to connect to bus: No such file or directory

Conclusion

I want to give a big shout out to the Windows development team and all the contributors BashOnWindows for all the work done on this, it has come a long way since the initial Creators update. I used to dread working on Windows with LEMP stack but now it's a breeze. I know a lot of people would just use a virtual machine but I still prefer this setup. Also, big shout out to Samuel Hilson for his article on this topic, this post is largely based on his work, you can find a link to his article in the resources section.

Hope you liked my article, please leave comments and share if you liked it!

Resources

Gist