Articles

Developing on Windows

I've been developing on Windows as my primary platform for about the last year and a half (and getting puzzled looks at conferences for about that long). I'm often asked how (or why) I do it, so as I've recently bought a new Surface Pro, here's my brief guide to developing (with Python) on Windows.

Background

I've been a Linux user since around 2004, using Red Hat, Gentoo, Debian and Ubuntu over the years. I still have a Linux laptop at work as my primary development machine; I enjoy Linux on the desktop a lot, and it took quite a bit to get me to change.

The main thing that changed in the Windows world was the introduction of the Windows Subsystem for Linux (WSL), sometimes also called "Bash on Ubuntu on Windows". WSL is a rather impressive piece of kernel engineering that allows Windows to natively run Linux applications - no virtual machines, no emulation, just a different frontend on the NT kernel. You can open the Windows Task Manager and just see bash or git right in there.

WSL brings you a complete Ubuntu userland, complete with apt-get, access to the Windows drive, and near-complete compatability with Linux ABIs (it even supports mmap and UNIX semaphores). This solved the missing piece of running either Windows or Mac for me prevously - substandard command line interfaces that forced you to run virtual machines for any development.

As for why I moved away from Ubuntu, it's a combination of bad support for pen, touch and compact hardware (like the Surface Pro), and poor support for high-end tools like Unity 3D and Adobe Premiere. Neither of these are issues at work, so I still run Ubuntu there.

The Windows (and especially Surface) ecosystem has come a long way, and the fact that I can click the end of the pen, OneNote pops open, and I can get to writing notes immediately is just one example of the integration and feature set that has me sold on those devices. Don't get me started on how the Surface Dock is finally a good laptop docking solution after trying about a decade of other options.

Hardware

The biggest complaint people often have going into the Windows ecosystem is how bad the hardware is. There's a lot of bad hardware out there, for sure, and everyone and their dog will try to sell you a Windows laptop with lots of weird stuff preinstalled.

There is, however, a subset of very good hardware, and that subset still spans a range of form factors that Apple just don't have pinned down yet, while being equivalent in build quality.

Here's my recommended list of hardware right now (June 2017):

  • Surface Pro, arguably Microsoft's flagship device and my personal favourite form-factor. It's small, it's light, it's great for drawing on the screen or using one-handed with touch, and still impressively powerful. Some people don't like that the keyboard has a free-moving hinge; it makes it work slightly less well in the lap, but not much, and it works way better in tight environments (e.g. airplane trays) because the kickstand offers a lot of stability. The keyboard is not perfect, but impressively good considering.
  • Surface Book, the Surface Pro's bigger sibling and where you should turn if you want more power, a normal laptop keyboard and form factor, and still want to be able to yank the screen off and draw on it. I used to use one of these as my main machine; I moved to a Surface Pro mostly because it's smaller, lighter, and much quicker to flip into drawing mode.
  • Dell XPS 13, one of Dell's best laptops and with build quality to match. Fantastic keyboard, and still has a touchscreen (once you use a laptop with one, it's hard to go back), but doesn't do any of the weird separation or tablet stuff. Also well-supported by Linux, unlike the Surfaces, so good if you want the option.
  • Corsair One, which is where you should turn if you're willing to sacrifice portability for an incredibly powerful desktop with an impressively small footprint and almost no fan noise. It's pricey, but only a bit more than the components inside bought separately, and you would never get it this small or quiet yourself.

There are other options, of course, including building your own desktop if you like that kind of thing (I do sometimes), but these are good, standard ones I can personally recommend. In particular, it's hard to go wrong with Microsoft hardware - the Surface Laptop and Surface Studio are also lovely, they just don't fill niches that I need.

Even better, if you live in a country with a physical Microsoft Store, their support is excellent and if you have a problem (or if you accidentally drop it and get the "Microsoft Complete" extended warranty), they'll swap it on the spot, sometimes even giving you the new model if the old one is no longer in production.

Setting Up

OK, so let's walk through how to set a Windows machine up for development in the way I like (and also point out a few of the things I fix with Windows along the way). Windows 10 is a good OS generally - it's fast, stable, and good at things like resolution scaling - but it has a few places where overzealous product design shoves ads in your face until you turn them off.

The process starts when you open a new PC and go through the first-time setup process. This has changed a little over the years, and currently features an over-enthusiastic Cortana talking to you (you can turn her off), but the basic things you need to do are the same:

  • Turn off tracking options - to Microsoft's credit, they do ask you directly now if you'd like to change these, and you can flip off ad tracking, sending typing/handwriting data and sending browsing data right here. I leave on location services and speech recognition, as I actually use those.
  • Use an "offline" (local) account for initial setup - this is a nitpick, but if you start with a Microsoft account, your user directory will only have the first five letters of your name (e.g. Users/andre for me). Once you have finished set up, you can immediately go and associate an MS account and it all works the same, but your user directory is now named nicely. If you don't care, or your name is 5 characters or less, you can skip this.

Once first-time set up finishes, there's a few more of the ad options to turn off and then Windows will be entirely ad-free:

  • In Settings, go to Personalisation and then Lock Screen, switch it from Windows Spotlight to an image, and turn off "helpful tips" to remove the weird notes about nature and stuff from the lock screen.
  • Still in Personalisation, go to Start and then turn off "Occasionally show suggestions"
  • Finally, open up Windows Explorer, then go to View > Options > View > Advanced Settings and turn off "Show sync provider notifications" to stop OneDrive info bars appearing when Windows thinks you might like them.

The last thing to do is to make sure BitLocker is enabled. Right click on the C: drive in Explorer and select "Manage BitLocker"; if it's not on, you probably want to enable it. On any recent machine it uses processor extensions for the encryption so it has very little overhead. Make sure you back up the key, though!

Package Management

The one downside of Windows compared to most Linux distributions is centralised package management; downloading endless installers is not fun. Thankfully, most of this can be achieved by using Chocolatey, which is a Windows package manager and handles installation and updates of most things. You can install programs with one command:

choco install vlc

And update them all in one go:

cup all

It can't handle everything, but most of the things it doesn't handle have their own updaters (in my case, the Adobe suite, Google Chrome, and Steam).

By default it will ask you to confirm installing every package, which can get tedious; I genenerally run this to turn that off:

choco feature enable -n allowGlobalConfirmation

You should always run it from an elevated command prompt, which if you're not familiar with Windows, you can just get by right clicking on the Start button and selecting either "Command Prompt (Admin)" or "PowerShell (Admin)", or using ConEmu as I cover below.

If you're moving from a previous Windows install, you can list what you installed in the previous Chocolatey install (and what's on the system not from Chocolatey) using:

choco list --localonly ---includeprograms

I save this to a text file and use it to know what to install on my new machine.

WSL

It's time to install WSL. I recommend you follow the official installation guide; just be aware that you will need a reboot after installing the WSL feature.

I also tend to add Hyper-V support when I'm in the Add/Remove Windows Features menu, so I can get it all done in one reboot and so I don't need to do it later when installing Docker for Windows.

Once the installation is complete, open the "Bash" application (hit the Windows key, type "bash", hit enter), and follow the instructions for a first-time setup. Once that's complete, you'll have a working Linux environment; you can apt-get install whatever you need, and this is where I usually link in things from the Windows folders (located under /mnt/c).

Note that you can access Windows files from Linux but not the other way around, so I usually host all my development files in my Windows user directory and then symlink it inside of Linux into the Linux home directory.

Once I'm done installing WSL I'll run a huge apt-get install of all the stuff I normally use (python, virtualenv, etc.), and then I can just get working. Since it's still native Windows under the hood, any servers you run here just appear on "localhost" and you can talk between apps on both the Win32 and Linux subsystems; I run the Microsoft-maintained Redis as a Windows service, for example, but WSL still sees it as locahost:6379. Docker setup is covered below.

The shell that WSL comes with is a bit basic, though, so let's install a better one and improve some other aspects of the Windows experience.

ConEmu

ConEmu is my preferred terminal program on Windows; it provides the feature I've used for many years, starting with yakuake on KDE, which is that it pops down from the top of the screen when you hit a hot-key (in my case, F12).

We can just use Chocolatey to install it:

choco install conemu

On first boot, you will get a small settings screen, but don't be fooled; the main settings screen ranks up there for having the most options and sub-options imaginable. Whatever you want to do, it's probably in here; apart from the Quake-style options, I usually change it so that the Ubuntu shell is the default shell for new tabs and change some of the keyboard shortcuts.

AquaSnap

Windows actually comes with some basic shortcuts for window tiling in the form of Win+Left and Win+Right, which snap windows to half the screen on the left and the right. I like a bit more flexibility, though, and so I use AquaSnap, which as well as having tiling options also does nice things like making windows transparent when you drag them and snapping them to each other.

Docker

The other key thing I use, and that can be a bit tricky, is getting Docker working. WSL does not yet natively support the namespacing needed to run Docker, so you need to use Docker for Windows, which uses a virtual machine to do everything (though it's wrapped up in a nice, easy-to-use way).

You can install Docker for Windows from the Docker site, and just follow the setup instructions to get it booted. This will install the Docker client and tools on Windows shells (cmd, powershell), but not inside WSL - there's a few more steps for that.

First, install the Docker tools inside the WSL Ubuntu environment:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce

Now, you'll need to set environment variables so Docker talks over TCP rather than trying to use a UNIX socket. Unfortunately, I have not yet found out where the client certs are for Docker for Windows, so I have to set an unsecure connection using this environment variable:

DOCKER_HOST=tcp://127.0.0.1:2375

And then, to make Docker listen on this port, select "General" > "Expose Docker without TLS" inside the Docker for Windows settings.

Next Steps

That's it for my basic setup; there are things particular to me, like my editor (Sublime Text) or my file sync solution (Syncthing) that I also install, but pretty much everything is available on Windows anyway so you have plenty of choice.

I'll leave you with a couple more tips in case you are not too familiar with modern Windows, that make it much more streamlined for me:

  • You can open any program or file by hitting the Windows key and just starting to type. I basically never even open the Start menu and click on things.
  • If you have things pinned to the taskbar, Win+1 opens/switches to the first one, Win+2 opens the second and so on. This way I know that Win+3 is always my editor, for example.
  • You can set Chrome applications and even websites to appear and function as separate windows - I do this for TweetDeck, Gmail and IRCCloud. You need to make a shortcut on the desktop (for apps, this is right click > "create shortcuts", for websites, it's "more tools" -> "add to desktop"), and then just right-click the shortcut and select "pin to taskbar". Now, it lives on the taskbar and you can open and manage it separately. I sort of wish Edge would get this too, as it's generally much better at battery usage; maybe it will one day.
  • Win+Ctrl+Left/Right switches virtual desktops, though you'll have to add them first in the task view (Win+Tab or swipe from left edge)
  • If you want a f.lux or Night Shift equivalent for changing the colour temperature at night, it's called Night Light and it's just in the display settings. You can find options to change screen scaling in there too, in increments of 25% (I usually run 175% scaling on the Surface screen and 100% on my normal monitors).
  • Windows 10 has a nice built-in screenshot tool called "Snipping Tool" that lets you select areas or windows. PrtScn still works if you like that sort of thing.
  • You can run Windows applications from inside WSL; try running notepad.exe and be very confused at what you have wraught.
  • If you want to run X applications from inside WSL, you can! Install XMing, set DISPLAY=:0, and be even more confused at what you have wraught.
  • If you don't like Ubuntu, you can run a variety of different distributions under WSL. There's an unofficial tool that does this and lets you switch, and Microsoft are going to add Fedora and Suse support officially in the near future.