Moving from OS X to Windows for Web Development

I have been an Mac user for most of my life and use a MacBook Pro as my daily driver for web development and general business tasks. Apple was a no brainier because of the superior build quality, integrated UNIX and app ecosystem. Since 2013 I used a 15″ MacBook pro and was absolutely thrilled with it. After 4 years of very heavy use it started to crap out (battery life sucked, graphics were glitching, etc..). So, I took it to the Apple store and looked to see what it would take to get repaired. After a diagnostic, they said they would need to literally replace everything but the hard drive and that would cost something around $600. That price was reasonable to me, the only issue is I would be 3-5 business days without a computer, which is not an option since I run my business from it. So I decided to get a maxed out 13″ MacBook Pro to try out while it was getting repaired, as I could sell my 15″ if I liked the new 13″ version.

I ended up liking the new 13″. Not loving, but just liking. I got in a car accident a few years ago and injured my back and am still dealing with daily pain. The 13″ is significantly lighter than my 4.5lb 15″ and that was enough of a motivation to keep it. I did note, however, that the 13″ was significantly less powerful than my 15″ from 4 years ago even though both cost about $3,000. Realistically as someone who does web development I don’t need a super powerful machine, so I was OK with the trade off.

Fast forward a month and I go to open my MacBook after lunch one day and the screen is black. I press the power and get nothing, so I figure it’s dead and I go to charge it. Still nothing. I think it might be my charger so I borrow a colleagues. Still nothing. Now I’m annoyed thinking my new computer is broken, but I reluctantly take it to the apple store. They verify that it is a hardware failure and offer to to perform a warranty repair. I do it, but am now frustrated as I’m going to be 3-5 days without a laptop which is why I purchased the new MacBook Pro in the first place.

After some thought, I decided to install Linux (Ubuntu) on my desktop PC that I rarely use. This wasn’t a huge deal for me as I use vim as my primary editor anyway and prefer working from the command line when possible. I then hit a snag. I have a 3 monitor “tie fighter” setup where I have a 27″ 4k monitor in the center and two 22″ 1080p monitors to each side, inverted on a 90-degree angle. Since I am pretty much unable (comfortably) to read 4k text at native resolution I need to upscale that display. This is fine on OS X and Windows, but for Ubuntu per-display scaling is not working properly. This meant that if I wanted to upscale my 4k I needed to run each of the 1080s at 720p which makes all of the apps look janky or be completely unusable. With that being said, I didn’t have much of a choice so I used that until my MacBook came back.

After about another month, it broke again. This time the OS wouldn’t boot. I couldn’t even get to recovery mode. So another trip the the Apple store and another 3-5 days out for repairs. Back to Ubuntu.

Then it broke again in January. The sound stopped functioning and other oddities. I went back to the Apple store visibly upset. This was now the third time I had to take it in for repairs and the lost productivity is costly. The people at the store were very helpful and offered to give me a brand new laptop (basically allowing me to return my old one and purchase a new one). I was grateful for this and used my new MacBook happily for a few months. I also purchased Apple Care $269 because I knew that the reliability of this device was now questionable.

I had the issues that everyone does with keys sticking, and I had occasional crashes and screen failures, but overall it worked. This served me pretty well until May. Then, I came into the office and opened up my laptop and started to wipe off the screen. That is when I noticed a small crack in the black bar below the screen next to the “MacBook Pro” logo. I was taken abash by this as I take extremely good care of my hardware. It’s been in a case since day 1, stays mostly on my desk, and I never dropped it or closed the lid with something left in between. After some research I found this forum thread with over 10 pages of complaints about similar issues.

Small hairline crack with no sign of impact.


At this point I am beyond frustrated with Apple as they have just accepted mediocrity as the norm. I will no longer be a customer nor recommend Apple products to anyone I know.

Windows to the Rescue!

I have been keeping an eye on Windows for a couple of years now and have been keenly interested in them ever since they released their Windows Subsystem for Linux (WSL) previously known as Bash on Windows. I tried using it a few times in the past, but ran into many issues getting my development environment set up. For a while, I had CYGWIN installed and SSH’d into an Ubuntu VM and that worked swimmingly. The issue with that is that if I was running this setup on a laptop, running a VM 24/7 would kill the battery life and degrade performance to an extent.

I am happy to say that WSL now works exactly as I need it to and I really don’t have any complaints. Some things I discovered and/or noticed:

You can run multiple distributions simultaneously

This is really cool. Being able to run Ubuntu + anything else in a non virtualized environment is awesome. Microsoft even created a useful tool wslconfig.exe that allows for easy configuration management/switching between distributions. This means you can test things without having to break you environment (see my next point).

Ubuntu 18.04 is still buggy

I am still running 16.04 as I found that the latest LTS is not working for whatever reason. Basically, I cannot get NGINX to properly pass to PHP (getting timeouts) and I am having issues accessing MySQL. I wouldn’t even call this an annoyance because I can operate on 16.04 without any issues. I look forward to running 18.04 when it’s stable.

You can use 3rd party terminals

Microsoft’s default terminal is pretty crappy. It gets the job done, but doesn’t have any of the niceties that I’ve come accustomed to. I like to heavily modify my color scheme and change the fonts – neither of which have easy configuration in the default terminal. The good news is that there are a lot of terminal emulators available. Here are a couple that I liked:

  • WSLTTY – This is my main driver and does everything I need.
  • WSL Terminal – I like this because it’s based on MinTTY which is what I ran on Cygwin so I’m used to the configuration
  • Hyper – This is an interesting choice. While I’m hesitant to use a terminal that is an Electron app, I do have to say that the interface and configuration is refreshingly simple.

You can edit/share files between WSL and Windows

This used to not always be the case. Previously it was warned that if you edited a WSL file on Windows you risked corrupting your system. This meant if I wanted to edit a WSL file in a GUI text editor it was not possible. Thankfully, this is no longer the case. The only caveat is that the file you’re editing can’t be in the WSL home directory. What this practically means for me is that I have my webroot set to a place in my windows user directory (/mnt/c/Users/zach/www/html) and everything works fine.

VS Code has WSL support?!

I have to say that I’m pretty impressed of Microsoft with this one. VS Code now has first-class support for files from WSL, so no more having to worry about line ending issues. It also has native support to run bash & debug NodeJS applications on WSL from within the editor. I now seriously considering trying out VS Code as my primary editor.

Docker works

I have been using containers more and more and I’m happy to know that Docker works on WSL. All you need to do is install Docker for Windows and then follow this official guide to connect to the Windows Docker Daemon from WSL. I haven’t experimented with Kubernetes on WSL yet, but that’s up next.


The takeaway here is that OS X is not the only viable machine for web development. With the huge drop in quality of their hardware and software it may be worth considering other options. Microsoft has been making huge strides to satisfy the developer community’s needs by creating WSL and making it intuitive and useful. Bravo Microsoft!

What are your thoughts? Have you tried creating a development environment in windows?


Getting Started with Kubernetes on GKE

Note: This article is a companion article to May’s GDG Cloud Philly meetup event. This article should still serve as a standalone guide to Kubernetes. If i’m missing something, contact me.

Kubernetes is undoubtedly one of the most trending technologies of 2018. With all major clouds adding support for the platform and increased investments from large companies, Kubernetes is slated to take over the web. You may be asking, “What is Kubernetes?”

Kubernetes is an open source production ready container orchestration platform. Put simply, it lets you easily manage containerized applications at scale. Kubernetes was created by Google and applies lessons learned from running billions of containers a week in production for over 15 years. It is built to run anywhere from your laptop, to a Raspberry Pi, to cloud VMs.

Why Use Kubernetes?

The first question you may be asking is, “Why should I use Kubernetes?” There are many reasons for someone to use Kubernetes that varies by use case and business type. For Example:

Enterprises & Large Businesses

Large businesses can benefit from Kubernetes

Run on bare metal hardware

While Kubernetes was designed to run in a cloud native environment, utilizing VMs, it does come at a performance cost. For example:

  • Hypervisor overhead – this is the host operating system that creates and manages virtual machines
  • Guest OS overhead – each VM you run has it’s own baseline storage, CPU, and memory needs.
  • Storage overhead – block storage is network based so there is latency as well as a hard limit on IOPS (really important for high read/write database or file operations

When running Kubernetes on bare metal you can have complete control over the hardware and can even configure different applications run on different machines (like have a database run on a server with an NVMe SSD or ECC memory).

Vendor Neutral Infrastructure

Many of the products and services that cloud providers offer are useful, but come at a cost. This cost is both financial (pay for what you use) as well as operational. For example, if you use Amazon’s Simple Queuing Service (SQS) for message queues and want to migrate to Google Cloud you’d need to modify your application logic to switch to Google’s equivalent Cloud PubSub. Instead you can just deploy a RabbitMQ pod within Kubernetes and not have to be concerned about changing clouds.

This also introduces the ability to have a multi-cloud or hybrid cloud infrastructure for extra redundancy in the case of something like a cloud-wide outage – which happens from time to time.

Variable Capacity

In many business cases, your computing needs does not stay the same on a day-to-day or year-to-year basis. Instead your capacity needs can change dramatically for things like traffic spikes, regularly ran jobs (like ETLs), or for long-running processes. With Kubernetes you have the ability to auto scale the cluster by adding new nodes when you need the increased capacity to and delete nodes when you don’t.

Multi Tennancy

It is dead simple to run multiple applications or microservices from the same cluster. Gone is the day where you need to maintain separate groups of infrastructure for each part of your application stack.

Possibility to add Preemptible/Spot instances for temporary capacity

Both Google and AWS offer instances that live for a “short” time at a steep discount from standard rates (up to 70% off!). This allows them to utilize excess capacity when it’s not being used. The catch is that instances can be deleted at any time (with 30 seconds notice) and can live for a maximum of 24 hours. If you have variable workloads it is possible to implement an architecture that can utilize these instances to optimize for cost or process things more quickly.

SMBs and Startups

Streamline DevOps and Production Engineering workflows

While large companies typically have separate production and DevOps teams, small businesses and startups likely do not. With Kubernetes it is easy to meld these workflows together to speed up the releases and make development workflows streamlined and predictable.

Multi Tennancy

Like with large businesses, small businesses can benefit from multi tenancy as well. Specifically, you can host internal and external applications on the same cluster (like a website, CI/CD suite, source control software, CRM, etc…) instead of having to create and manage these services separately.

Infrastructure can grow with your needs

This is especially important for growth trajectory startups. Kubernetes gives you the ability to start with a relatively small cluster and grow as usage and application complexity increases.


Kubernetes is modular, so you have the ability to only scale the applications that you need to. If you need to add more front end services you can without also having to also scale back end services.

Cost Optimizations

If you are using GKE you have the ability to easily optimize pricing with committed use discounts. The basic logic is that you agree to pay for servers for a specified length of time (1 year or 3 years) and you get a heavy discount of up to 57%. Unlike other services where you have to commit to a specific machine type for a period of time, Google Cloud allows you to to commit to usage at a CPU core and memory level and can deploy it to any type of server you’d like. This allows you to resize instances as needed without having to worry about being stuck in a contract for the previous one.

Why use Google Kubernetes Engine?

I think the general selling points of Kubernetes are pretty compelling, but why would you want to use a managed Kubernetes service  like GKE instead of managing the cluster yourself?

The first reason is that configuring your own cluster is hard and tedious process. In my first exposure to Kubernetes, which was at a training event, it took several hours of work to get the test cluster set up and that was with provisioning scripts being provided to us. It is highly recommended not to manage your own clusters. If you are interested in learning more about setting up your own clusters, I recommend Kelcey Hightower’s Kubernetes the Hard Way course.

In GKE, the Kubernetes cluster is fully managed by Google and is constantly monitored and maintained by their Service Reliability Engineering (SRE) team. Members of this team literally wrote the book on Service Reliability Engineering and there is arguably no other team more qualified to keep a service up and running than Google’s.

GKE also gives you the ability to auto scale and auto upgrade your clusters.

You also have the ability to use Google’s Container Optimized OS which is specifically made to run containers and Kubernetes and is optimized to be minimalist and performant. With Container Optimized OS you no longer need to worry about OS updates as they auto update themselves.

GKE gives you the ability (in beta) to use GPUs to run AI workloads.

Google gives you the ability to run GKE in regional clusters (currently in beta). This allows you to have extra redundancy in both the Kubernetes master and nodes to hedge against zonal outages and hardware failures.

Best of all running Kubernetes on Google Cloud is FREE! You obviously pay the standard rates for compute instances but there are zero charges for running them in Kubernetes Engine.

Understanding the basics of Kubernetes

Kubernetes Master. This is a collection of three processes that run on a single node in your cluster, which is designated to be the master node

Nodes. Individual servers in your cluster that are controlled by Kubernetes.

Deployments. A deployment in kubernetes provides declarative updates for pods and replica sets. A deployment object is used to describe the desired state and the deployment controller changes the state to your desired state.

Kubectl. Kubectl is a utility to control Kubernetes clusters from the command line.

Pods. A pod the smallest deployable object in Kubernetes. They represent the running processes in your cluster. Pods can either run a single container or multiple containers that need to work together.

Services. A service is a grouping of pods that are running on your Kubernetes cluster. If you have experience with object oriented programming, you can think of a service being an object with deployments being it’s class.

Run Kubernetes on GKE

Install Google Cloud SDK

Google Cloud SDK is the easiest way of managing Google Cloud. It is a set of command line utilities that can do anything that you can do from within their web control panel – including configuring Kubernetes. You can install the Google Cloud SDK for your operating system by following the installation instructions here.

Install kubectl

gcloud components install kubectl. This can also be installed via homebrew if you’re on a Mac.

Create a cluster

To create a cluster, type in the following command. This will create a standard cluster with 3 nodes.
gcloud container clusters create gke-test

We then need to get authorization credentials to be able to access/modify the cluster
gcloud container clusters get-credentials gke-test

Create a deployment

kubectl run hello-server --image --port 8080

Scale your service

You may want to scale your service so when traffic goes to the site it is balanced between 3 pods:

kubectl scale deployment hello-server --replicas=3

Expose the service

kubectl expose deployment hello-server --type "LoadBalancer"

You can now access your service from a web browser

Delete your service

Now when we’re done make sure you delete your service to clean up any load balancing forwarding rules.

kubectl delete service hello-server

Delete Cluster

Once you’re done with Kubernetes, make sure you delete your cluster.

gcloud container clusters delete [cluster_name]

Create Simple CSS Arrows


There are a lot of articles and generators out there on how to create CSS bubbles. Most of them are great, for 99% of the time. When I was creating arrows for one of my sites, WP Improve, I ran into a lot of issues. I was using the Advanced Custom Fields WordPress plugin to allow for user defined colors for each section of my website, the arrow at the end of the section would then take on the same color as the section itself. Every tutorial & generator I used either didn’t display the right color, or the arrow would not show up at all. It was time for me to come up with my own solution.

My HTML looked like this:

I am using inline CSS for colors because each section is defined dynamically in WordPress, so the easiest way to do this is to add it inline.

Next is the CSS for the arrows itself. This one of the finer points of CSS, we can take advantage of inheretence to make the color of the arrow the same color as the parent div, without having to code custom colors into each arrow:

The parent div needs to be relatively positioned.

For the :after pseudo selector we do the following things:

  1. Absolutely Position The Element
  2. Create a 20px square
  3. Rotate it 45 degrees to create a diamond
  4. Position it 10px below the div (to get the “arrow” effect)
  5. Center it by making it left 50% then adding a -10px margin to compensate for half the width of the element.
  6. Adding a z-index to make sure the arrow is always on top

Here is an example of this working in action:

See the Pen JGELXW by Zach Russell (@protechig) on CodePen.

How do you prefer to make your CSS arrows?