WSL
For many years, developers who like Windows OS have lived on dual boots and virtual machines. Microsoft’s introduction of Windows Subsystem for Linux (WSL) was one of the best moves the company made in an effort to make Windows a one stop for both personal computing and development. I live on both Windows and Linux and therefore to me, this was a long awaited feature.
WSL is disabled by default and can be enabled by going to “Add Optional Programs and Features” in Windows control panel or running the following command followed by a reboot.
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
In settings, enable “Developer Mode” and then download your favorite distro from Microsoft Store. Once download is complete, open Command Prompt and type bash
. Follow the prompts to create an account.
Developing PHP apps on Homestead
In the last few years, I have been developing on SP4 with high end specs and it has served me well. My environments ranged from WAMP servers to custom installations. It became tricky developing solely on Windows and deploying to Linux servers. I encountered random and unexpected behaviors in applications that consumed time to fix. I then settled on Homestead using Vagrant and Virtualbox. Virtualbox creates virtual network Ethernet cards that also became a pain when developing React Native apps using Expo. By default, Expo picked the Virtualbox Ethernet IP to serve the app, which obviously was not available to Android phone for testing. I had to disable those virtual cards every time I was developing using Expo.
When running the environment on top of using multiple tabs on Chrome, phpStorm, Git terminal and a few other programs on the host machine, CPU usage would spike and response on the idea would decrease.
Making the switch. Setting up my WSL environment and shelving Homestead.
After searching for a better and viable solution online, I came across Laragon, a portable isolated dev environment, I was sold… almost. I checked them out. Installed, configured, and up and running within a few minutes. When I launched it, I found that I had Commander terminal and Notepad++, all of which I didn’t need since I use Sublime Text and VS Code for various quick code editing tasks. I liked the portability aspect and ability to create sites and setup hosts file automatically, and the small memory print. The problem was, I have to switch root directory on the program each time I was working on a different project and I didn’t need many of the other features they have to offer. I spend a lot of time on the Linux terminal and thus I would still have to work with Laragon and Ubuntu in addition. So, why not make Ubuntu on WSL do the same work? A few minutes of initial setup, then replicate in future projects. WSL has extremely low memory usage and barely affects startup time on my machine. So in my process to customize WSL, this is what I came up with.
#!/bin/bash sudo apt-get update sudo apt-get install apache2 mysql-server php72-cli git sudo service apache2 start sudo service mysql start sudo service php7.2-fpm start #Mailhog -optional git clone https://github.com/mailhog/MailHog.git mailhog git clone https://github.com/mailhog/mhsendmail.git sudo cp mailhog /usr/local/bin/mailhog sudo cp mhsendmail /usr/local/bin/mhsendmail # Create a script that will be run from Windows task scheduler mkdir -p ~/.local/bin/ echo "service apache2 start" >> ~/.local/bin/mydev-env.sh echo "service mysql start" >> ~/.local/bin/mydev-env.sh # add more stuff here to run on startup chmod +x ~/.local/bin/mydev-env.sh ln -s /mnt/c/MyDevDir /var/www/
## add the following to your .bash_aliases and source it
function new-site(){
# Get variables
echo Enter Server Name EX. myproject.test
read SERVER_NAME
echo Enter Document Root /var/www/*myproject*
read DOC_ROOT
# Paths
A2_SITES_AVAILABLE=/etc/apache2/sites-available/
A2_SITES_ENABLED=/etc/apache2/sites-enabled/
WIN_HOSTS=/mnt/c/Windows/System32/Drivers/etc/hosts
THE_FILE=$SERVER_NAME.conf
# Create the file
touch $THE_FILE
# add site configuration
echo Writing configuration to $THE_FILE...
printf "\n<VirtualHost *:80>" >> $THE_FILE
printf "\n\tServerName $SERVER_NAME" >> $THE_FILE
printf "\n\tServerAlias www.$SERVER_NAME" >> $THE_FILE
printf "\n\tDocumentRoot /var/www/$DOC_ROOT" >> $THE_FILE
printf "\n\n\tServerAdmin webmaster@localhost" >> $THE_FILE
printf "\n\tLogLevel debug" >> $THE_FILE
printf "\n\n\tErrorLog ${APACHE_LOG_DIR}/error.log" >> $THE_FILE
printf "\n\tCustomLog ${APACHE_LOG_DIR}/access.log combined" >> $THE_FILE
printf "\n</VirtualHost>\n" >> $THE_FILE
# copy the file to available sites
echo Copying config file to available sites...
sudo cp $THE_FILE $A2_SITES_AVAILABLE &&
# move the file to enabled sites
echo Moving config file to enabled sites...
sudo mv $THE_FILE $A2_SITES_ENABLED
# restart Apache server
echo Restarting server
sudo service apache2 reload
# add the site to Windows hosts file
echo Adding site to Windows hosts...
printf "\n127.0.0.1\t$SERVER_NAME" >> $WIN_HOSTS
}
https://gist.github.com/jgmuchiri/a3e0c6bb5340dad57dc31e3a6bea3f9d
Next time you need to create a new site, simply open Ubuntu or Bash from your Windows host as administrator, type new-site and hit enter. Answer the 2 prompts (site domain e.g. mysite.test and document root e.g. mylaravelsite/public) and you are all set.
What this code does.
- Create an apache2 site configuration
- Set the site’s document root
- Add the site to your Windows machine hosts file
- Restarts your Apache server
You should now see the site load on your browser at http://mysite.test
Since you cannot run a ‘true’ service on startup in WSL, you can use this workaround to run a script when the machine boots.
mkdir -p ~/.local/bin/
echo "service apache2 start" >> ~/.local/bin/mydev-env.sh
echo "service mysql start" >> ~/.local/bin/mydev-env.sh
chmod +x ~/.local/bin/mydev-env.sh
Then, allow your WSL account to run root commands without password
sudo visudo
john ALL=(root) NOPASSWD: /home/john/.local/bin/mydev-env.sh
Create a login script that runs this command
bash.exe -c 'sudo ~/.local/bin/mydev-env.sh'
Or simply create as scheduled task using this command
SCHTASKS /Create /SC ONLOGON /TN "Start My DEV Env" /TR "bash.exe -c 'sudo ~/.local/bin/mydev-env.sh'"
To run mailhog, you can either type mailhog
on the terminal or specify ips and ports.
mailhog \
-api-bind-addr 127.0.0.1:8025 \
-ui-bind-addr 127.0.0.1:8025 \
-smtp-bind-addr 127.0.0.1:1025
Also specify mhsendmail
in your php.ini
sendmail_path = /usr/local/bin/mhsendmail
Your Windows mount directory can be anywhere. Just change the ln command to create the symbolic links to the specific directories.
Remember to backup your work often. You never know when lightening may strike! You can backup your personal files to a local external backup media and your code to a remote repository. Github, Gitlab and Bitbucket are some of the services I regularly use.
Happy coding!