How to Set Up Docker and Windows Subsystem for Linux: A Love Story

As a seasoned developer who‘s spent countless hours in Linux terminals, I‘ll admit I was once skeptical of Microsoft‘s efforts to bring Linux tooling to Windows. But just as the old adage says, "don‘t knock it ‘til you‘ve tried it" – and try it I have. After spending quite some time with Windows Subsystem for Linux (WSL) and Docker together, I‘ve come to appreciate the incredible potential of this unlikely power couple.

In this guide, I‘ll walk you through the process of setting up Docker and WSL to work together seamlessly, so you too can experience the joys of this match made in developer heaven. I‘ll share detailed steps, real-world examples, data-driven insights, and a few personal anecdotes along the way.

Why Docker and WSL Together?

Before we dive into the technical nitty-gritty, let‘s take a step back and examine why this combination is so potent, especially for developers.

WSL, if you‘re not familiar, is a compatibility layer that allows you to run a full Linux environment directly on Windows, without the overhead of a virtual machine. It‘s not an emulator or a layer on top of Windows – it is, for all intents and purposes, Linux. You get the beloved Bash shell, Linux utilities, and the ability to run Linux executables and libraries natively on Windows.

Docker, on the other hand, is a platform that allows you to develop, ship, and run applications in containers. Containers bundle an app with all its dependencies in a standardized unit, ensuring that it will always run the same, regardless of the environment. Docker has become an industry standard, with a report from Datadog showing that adoption grew by over 40% in 2020 alone.

When you bring Docker and WSL together, you get a development environment that combines the strength of both. You can use WSL for your Linux-based tooling, utilities, and workflows, while leveraging Docker for packaging and deploying your applications consistently.

This combination has proven especially powerful for web development. As Microsoft‘s own Sarah Cooley points out in a blog post:

"With WSL and Docker you can use Linux command-line tools to quickly spin up a LAMP stack to host your website or blog, use Windows IDEs and text editors to update the content, source control with git, and even deploy your site using the Azure CLI right from the Linux shell."

In essence, Docker and WSL together allow you to use the best tools from both the Linux and Windows worlds, without compromise. It‘s like having your cake and eating it too!

System Requirements and Setup Considerations

Before we start installing anything, it‘s important to make sure your system meets the requirements and to be aware of potential setup hurdles.

To run Docker Desktop, the most straightforward way to get Docker on Windows, your system needs:

  • Windows 10 64-bit: Pro, Enterprise, or Education (Build 16299 or later) or Windows 11
  • Hyper-V and Containers Windows features enabled
  • At least 4GB of RAM

If you‘re on Windows 10 Home, you can still use Docker, but you‘ll need to install Docker Toolbox instead, which uses Oracle VirtualBox for virtualization. We‘ll cover that process in a bit.

For WSL, you‘ll need:

  • Windows 10 version 2004 or higher (for WSL 2) or Windows 11
  • At least 4GB of RAM (8GB recommended for optimal performance)

It‘s worth noting that while WSL 1 is available on all versions of Windows 10, WSL 2 offers significant performance improvements and is generally recommended for development. We‘ll be using WSL 2 in this guide.

With these requirements in mind, let‘s start setting up our environment!

Installing WSL 2

First, let‘s get WSL installed. Here‘s a step-by-step breakdown:

  1. Open PowerShell as Administrator and run:

    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

    This enables the Windows Subsystem for Linux feature.

  2. Reboot your machine to complete the WSL install.

  3. Set WSL 2 as your default version:

    wsl --set-default-version 2
  4. Install your Linux distribution of choice from the Microsoft Store. I recommend Ubuntu, as it‘s well-supported and popular in the WSL community.

  5. Launch your installed distribution from the Start menu and follow the setup prompts to create a user account and password.

And voila, you now have a Linux environment on your Windows machine! Let‘s move on to Docker.

Installing Docker Desktop

If your system meets the requirements for Docker Desktop, the installation is quite simple:

  1. Download Docker Desktop from the official Docker website.

  2. Run the installer, granting it permission to make changes to your system when prompted.

  3. Follow the installation wizard, accepting the default options. Make sure the "Install required Windows components for WSL 2" option is checked.

  4. Once installed, reboot your machine to ensure all changes take effect.

After rebooting, Docker Desktop should start automatically. You‘ll know it‘s running when you see the whale icon in your system tray. Open a terminal and run docker --version to verify a successful installation.

Setting Up Docker Toolbox (Windows 10 Home)

For those on Windows 10 Home, Docker Toolbox is the way to go. Here‘s how to get it set up:

  1. Check that your Windows version is up to date, as Docker Toolbox may not function correctly on older builds.

  2. Enable virtualization in your BIOS settings. The exact steps vary by system, but generally involve rebooting into the BIOS menu and looking for an option like "Virtualization Technology" or "VT-x".

  3. If Hyper-V is enabled, you‘ll need to disable it, as it conflicts with VirtualBox. Open an admin PowerShell prompt and run:

    bcdedit /set hypervisorlaunchtype off

    Then reboot your machine.

  4. Download and install the latest versions of Docker Toolbox and Oracle VirtualBox.

  5. Launch the "Docker Quickstart Terminal" shortcut that was created on your Desktop. This will create a default virtual machine to host your Docker containers.

With a bit of command-line magic, you‘ll be able to use this Docker Toolbox installation from your WSL environment. More on that shortly!

Linking Docker and WSL

Now for the exciting part – getting Docker and WSL to communicate! The goal is to be able to run Docker commands from within your WSL environment.

Fortunately, WSL has access to Windows executables. This means we can call the Docker CLI directly from Bash:

docker-machine.exe ls

This command lists the Docker machines currently available. If the default machine isn‘t running, start it with:

docker-machine.exe start

Next, we need to set up the environment variables in WSL to talk to this Docker machine. Normally, docker-machine env provides this info, but it‘s formatted for cmd.exe rather than Bash.

However, we can ask it nicely to speak Bash instead:

docker-machine.exe env --shell bash

This outputs something like:

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://123.45.67.89:2376"  
export DOCKER_CERT_PATH="C:\Users\YourName\.docker\machine\machines\default"
export DOCKER_MACHINE_NAME="default"
export COMPOSE_CONVERT_WINDOWS_PATHS="true"
# Run this command to configure your shell: 
# eval $(docker-machine env --shell bash)

Notice that DOCKER_CERT_PATH is pointing to a Windows-style path. We need to convert that to a Unix-style path for WSL to understand.

This is where the handy wslpath utility comes into play:

export DOCKER_CERT_PATH=$(wslpath "$DOCKER_CERT_PATH")

With the environment variables set, you can either eval the docker-machine env output as suggested, or simply copy-paste those export lines into your .bashrc file for persistence across sessions.

Finally, install the Docker CLI tools inside WSL. For Ubuntu or Debian-based distros:

sudo apt update
sudo apt install docker.io docker-compose

Let‘s test it out with a classic "hello-world" container:

docker run --rm hello-world

If you see a friendly "Hello from Docker!" message, congratulations! You‘ve successfully married Docker and WSL.

Handling Volumes and Ports

There are a few quirks to be aware of when using Docker from WSL, particularly around mounting volumes and exposing ports.

For volume mounts, you need to use Windows-style paths, as that‘s what the Docker daemon expects. In WSL, /mnt/c maps to the C: drive, /mnt/d to D:, and so on.

So a command like:

docker run -v /mnt/c/Users/YourName/project:/app myimage

Would mount the C:\Users\YourName\project directory into the container at /app.

When it comes to exposing ports, the behavior differs slightly between Docker Desktop and Docker Toolbox:

  • With Docker Desktop, exposed ports are accessible on localhost as you‘d expect.
  • With Docker Toolbox, you need to use the IP address of the Docker Machine VM instead.

You can retrieve this IP address with:

docker-machine ip

Then access your application at http://<docker-machine-ip>:<port>.

Best Practices and Tips

To make the most out of your Docker + WSL setup, here are a few best practices and productivity tips:

  • Use Docker Compose for multi-container applications. Compose allows you to define and run multi-container Docker applications, which is handy for more complex setups. Microsoft offers a great tutorial on using Compose with WSL.

  • Leverage WSL‘s interoperability with Windows. You can execute Windows binaries from within WSL, access the Windows filesystem through /mnt/, and even use Windows applications to edit files in your WSL environment. Make use of this interoperability to craft a workflow that combines the best of both worlds.

  • Keep your Docker images small. Smaller images are faster to build, push, and pull. Some tips: use small base images like Alpine Linux, leverage multi-stage builds, and clean up unnecessary files in your Dockerfile.

  • Use a Docker ignore file. By creating a .dockerignore file, you can prevent unnecessary files (like .git or node_modules) from being included in your container, resulting in smaller images and faster builds.

  • Regularly prune unused containers and images. Over time, unused containers and images can accumulate and consume significant disk space. Regularly clean these up with commands like docker container prune and docker image prune.

Conclusion

Setting up Docker and WSL to work together may involve a few hoops to jump through, especially if you‘re on Windows Home, but the payoff is well worth it. With this potent combination, you get the power and flexibility of Linux tools alongside the ease and familiarity of the Windows environment, plus the consistency and portability of Docker containers.

While we‘ve covered the fundamentals in this guide, there‘s always more to learn. I encourage you to dive deeper into Docker and WSL, experiment with different setups and workflows, and find what works best for you.

Happy coding, and may your development environment be as powerful as it is flexible!

Additional Resources

Similar Posts