Running a Linux desktop just for development purposes is a hassle. The folks at r/linuxmasterrace would hate me for this, but the Year of the Linux Desktop isn't here, and won't be here for a while.

Sure, if all you do is do software development then using a full-time Linux desktop is fine. Dual-booting has its audience, it just isn't for me. I hate maintaining two systems when I don't need to. Also, with the entire mess the Linux desktop has (Wayland, questionable decisions by the GNOME devs and KDE being a pain in the butt to configure being a nice summary), it's not worth it to consider using one at the moment.

So, this is my guide for web developers who want to stick to Windows for purposes other than development (graphics design, gaming, etc.) but don't want to run the traditional XAMPP stack and the terminal with no ANSI support.

Why drop XAMPP?

No matter how easy XAMPP makes things (I even wrote an app that takes care of virtual hosts for XAMPP on Windows), it's no replacement for the real thing. For starters, when you're developing PHP, it's a 99% chance that your production server will be Linux-based.

Also, have you seen how the Windows terminal handles colors? It's a freaking mess out there. It may not be a big thing to you, but as a sysadmin and developer in one body, I use colors to differentiate critical errors from information entries.

Granted, there's Windows Subsystem for Linux, but the point was to make things work as close as it can to production. Running a subsystem won't help with dealing with all the systemd services I sometimes have to write for background processes, since my production servers use systemd-based init systems (don't kill me, please).

Virtualize all the things

My VirtualBox setup running an Ubuntu 18.04 Server instance.

VirtualBox, in case you didn't know, is a free app to create and manage virtual machines. This means you can run an entirely different operating system (be it Windows, Linux-based or BSD-based), which we call a guest, to your current operating system, which we call a host.

The setup is on boot, a headless (an operating system that runs in the background, so to speak) instance of Ubuntu Server 18.04 will start with the components you'd expect:

  • OpenSSH Server (for SSH so you can connect via PuTTY)
  • a web server (my personal choice is nginx, but you do you)
  • an SQL server (I use MySQL for most cases, but I'm also exploring MongoDB)

Note that you can run any operating system you want and any dev stack you want. Since I am a PHP Software Engineer, my stack is a basic LAMP/LEMP for the most part.

On the host, I have my tools:

  • my IDE (I use phpStorm and a smothering of others)
  • PuTTY (to connect to the SSH server)
  • Git (for version control, obviously)

I have a shared folder called "Projects" on the host (it's in my user directory in Windows), and is set to auto-mount on /projects inside the guest instance.

Setting up

I'm not going to go into detail on how to install VirtualBox, there's a ton of tutorials for that. Here, let me Google that for you.

Next, setup your guest operating system. I just slapped on Ubuntu Server 18.04 because while all my production servers run CentOS, I just want to code and have my instance set up faster, plus Debian-based distros have sane defauls compared to CentOS for some reason (virtual hosts being split up by default on Debian/Ubuntu is one vs. CentOS packing them all into one file. Note that you can also split up virtual host configs in CentOS. I just don't have the time nor patience to do so.)

Now, if you'll look at the screenshot above, I have two: Ubuntu Server 18.04 and Ubuntu Server 18.04 (Image). The image instance is basically a clone of my server after all the preliminary setup has been done: user accounts, partitions and swap set up, guest additions installed and the like.

Installing Guest Additions

Note that you need the VirtualBox guest additions installed in your guest instance for shared folders to work properly.

To do this on a Debian/Ubuntu-based guest OS, click on your VirtualBox window and click Insert Guest Additions CD image... (you need the VirtualBox Extension Pack installed on the host OS), then run the following as root on your guest OS:

mount /dev/cdrom /mnt
cd /mnt
sudo apt install build-essential perl make gcc -y
./VBoxLinuxAdditions.run

After it's installed, unmount the CD image and reboot:

umount /mnt
reboot

You can now add shared folders to your guest OS. Simply edit the settings of your instance and click on Shared Folders, then add a new entry.

Your mount point is where VirtualBox will mount the folder on your guest OS.

If you save that and reboot your instance, you can see that it will appear in /projects:

There's now a /projects folder.

Let's add permissions to our user to have access to that folder by adding the vboxsf group to our user. In this case, the user is liam. Adjust accordingly, obviously.

usermod -aG vboxsf liam
chgrp -R vboxsf /projects

Now, you can access your files on both your host and guest systems without the mess of managing custom permissions.

File operations can work both ways on the shared folder.

Forwarding Traffic

We need to forward our ports so that our host and guest OS can see each other over the network. Simply go to VirtualBox, right-click your instance and click on Settings.

Go to the Network section. Make sure the value of "Attached to" is set to NAT. Now, click on the Advanced drop link to expand the view, then click on Port Forwarding. You'll see the following screen:

A screenshot of the Port Forwarding Rules window.

You can use the above values to add ports. Note that I set the host port for SSH is 10022 because I might use port 22 for something else on my host. IP Addresses for both Host and Guest are optional, so leave them blank.

Your Host Port is the port that should be accessible over your host via 127.0.0.1. So, if you want to access your web server on your host via http://localhost:8080 or http://127.0.0.1:8080, you need to set your Host Port to 8080.

Your Guest Port is the port inside your guest. Out of the box, web servers use port 80, SSH uses port 22 and so on. For a list of what ports are used by which programs, you can use netstat:

See the Local Address column but disregard the IP addresses. The port is the number after the colon.

In the above screenshot, SSH is attached to port 22 and is bound to all address interfaces inside the guest (as denoted by 0.0.0.0).

Setting up your stack

Now, however you want to setup your stack is up to you. LAMP and LEMP stacks are common, and I suggest you use the Ondrej PPAs for PHP and nginx-mainline.

I use the Acrylic DNS proxy on my host to make my hostnames accessible on my host's browser. My Acrylic HOSTS file is composed of the following line:

127.0.0.1	localhost *.local

This means that localhost and anything that ends in .local will point to 127.0.0.1, the address of the host where VirtualBox is installed. You can also use any other DNS proxy you wish or set up your HOSTS file manually.

A guide on setting up the Acrylic DNS Proxy for Windows 10 can be found here.