Preparation for Developing Laravel Apps on WSL2
Website development comes with a complexity cost in setting up the right development environment that it ends up taking much of your time from actual development.
While enthusiastic about linux. Windows is still my daily driver due to work. On spare times I would work on my projects discretely at the office. But having linux at home and windows at the office makes me waste time applying dos2linux on all the code that I worked on during the day.
So I tried WAMPServer, XAMPP, laragon and Docker. These are great products. But I prefer to use nginx as opposed to apache2. Docker would have been the best way but due to the complexity and the learning curve I have to ditch it due to my limited time. That's when it hit me that Docker uses WSL2 anyway why not just use WSL2?
So after cleaning up my System. Reinstalled my WSL2 Ubuntu distro. The steps below are what I did to start developing my laravel project on WSL2
Updating the System
sudo apt update && sudo apt upgrade -y && sudo dist-upgrade -y && do-release-upgrade
Remove apache2
type apache2 >/dev/null 2>&1 && { sudo apt purge apache2 apache2* }
Install php, nginx, mysql
sudo apt install php php php-fpm php-mbstring php-xml php-bcmath nginx mysql-server
Install composer
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
Note: Instructions taken from getcomposer.org
Install nvm, npm, nodejs
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
nvm install --lts
Note: Instructions taken from learn.microsoft.com
Add User to www-data group
sudo usermod -a -G www-data <username>
Create a Laravel project
Directories
Begin by planning your directory structure. Commonly used pattern is to use '~/projects/<project name>' to host the actual project then symbolically linking the directory to '/var/www/html/<project name> then setting the correct owner and permissions.
mkdir -p ~/projects/<project name>
sudo ln -s ~/projects/<project name> /var/www/html/
Note: mkdir -p creates the directory you want including all the parent directories if needed
Check if everything is in order (Optional)
A Udemy instructor Piotr Jura has created a php script to check if your system is ready for Laravel Projects
check.php <- this will take you to a github gist.
Alternatively we can download the file using curl...
https://gist.githubusercontent.com/piotr-jura-udemy/1037a78c7e7cb1074125b453972d2fcf/raw/1fddb5c4072bb536c80224cb6dd2c289646f2434/check.php
Option 1:
mv check.php to temp
touch check.php
echo '#!'"$(which php)" > check.php
echo "$(cat temp)" >> check.php
chmod +x check.php
./check.php
Option 2:
php check.php
Create Project
cd ~/projects/<project name>
composer create-project laravel/laravel .
Change Ownership
sudo chown -R $USER:www-data ~/projects/<project name>
Change Permissions
# set the proper permissions for folders and files
sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;
Note: Taken from this stack overflow answer
Create mySQL Database & User
sudo mysql -e "CREATE DATABASE '<database>';"
sudo mysql -e "CREATE USER '<username>' IDENTIFIED by '<password>';"
sudo mysql -e "GRANT ALL PRIVIlEGES on <database>.* TO '<username>';"
Note: Replace <database>, <username> and <password> to actual values
Modify .env File
Off the shelf a laravel app uses SQLite.
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
Excerpt of default .env
cd ~/projects/<project name>
nano .env
Modify the .env file.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<database>
DB_USERNAME=<username>
DB_PASSWORD=<password>
There are other fields on this file that you might want to change like APP_NAME
but for our purpose the above is enough for now.
Create/Modify nginx conf
sudo nano /etc/nginx/sites-available/<project name>
Copy and paste below conf. make sure to change those enclosed in angle brackets to correct values. It is also possible to add an entry in your windows host file and use that instead of localhost.
[default]
server {
listen 80;
server_name localhost;
root /var/www/html/<project name>/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
[/default]
Once that is created, symbolically link it to sites-enabled...
# do this if using localhost
sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/<project name> /etc/nginx/sites-enabled/<project name>
Bring it Live!
cd ~/projects/<project name>
php artisan migrate
sudo systemctl start nginx
sudo systemctl start mysql
After this step just open a browser and type localhost
Optional:
cd ~/projects/<project name>
code .