Is Docker slowing down your PC? Try this...

Photo by Ian Taylor on Unsplash

Is Docker slowing down your PC? Try this...

How to Run Docker in WSL Without Using Docker Desktop: Step-by-Step Guide

Introduction

When working with Docker on Windows, many developers opt to use Docker Desktop for its convenience and integration. Docker makes it easy to distribute your code to your team members without having to go through the pains of setting up their environment or switching versions of software every time.

However, if you prefer a more streamlined setup or wish to avoid Docker Desktop, you can run Docker directly within Windows Subsystem for Linux (WSL). This guide walks you through setting up Docker in WSL, resolving common issues, and ensuring a smooth Docker experience.

PS: If you're in a hurry, skip over the next two subheadings. But if you do read, you will appreciate the journey more.

Quickest way of building your software with Docker

The fastest way to use Docker in Windows is via Docker Desktop. If you have your files sitting at C:\Users\John\projects, you really just need to start the Docker engine, and you can continue developing (Assuming you already have your Dockerfile or docker-compose file set up).

This approach is great for a start but you will most likely run into performance issues. Serious performance issues. And good luck to you if you only have 4GB RAM! This can be a challenge, especially with limited resources. My computer kept freezing and I ultimately uninstalled Docker for a long time.

Eventually, the problem of switching environments too often led me back to Docker. And then I was forced to research. This led me to explore and arrive at the next iteration in my setup.

An improved way: Docker with WSL

If you have WSL, you can move your project files into your Linux folder so that they sit at ~/projects/ instead. Then you just need to fire up Docker Desktop, spin up your WSL instance, and then serve or run your project. You would need to configure Docker Desktop to communicate with the Linux distro.

This is also a very valid way of doing things. But lately, I have been wondering if it was possible to further boost the performance of my apps by completely bypassing the need for Docker Desktop. After all, the desktop app was made for Windows compatibility. But WSL actually functions like a full OS on its own. So what if we could pretend we were running Linux natively and just install Docker there directly?

The tradeoff?

The tradeoff is that we definitely lose the GUI experience. We would need to rely on commands to do everything. But I would rather it be super fast without a GUI than to have it super slow with a GUI.

I have a desktop PC which I wanted to dedicate to frontend work, while my smaller-screen-but-more-powerful machine handles backend work. The desktop struggles to run Docker Desktop, even though it has 16GB RAM and a fast i7 processor (the same specs as the smaller machine). I couldn't figure out why this was happening, but for this reason I decided to go with the approach we're about to unravel.

Prerequisites

  • Windows 11 (Win 10 users, read this)

  • WSL installed and running Ubuntu 20.04 or greater. You can follow this guide.

Installing Docker Engine on WSL 2

This section will guide you on installing Docker's core engine in your Linux distro within WSL.

  • Open your WSL terminal (e.g., Ubuntu).

  • Update the Package Index:

      sudo apt-get update
    
  • Install Required Packages:

      sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
    
  • Add Docker’s Official GPG Key:

      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
  • Add Docker’s APT Repository:

      sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    
  • Update the Package Index Again:

      sudo apt-get update
    
  • Install Docker Engine:

      sudo apt-get install -y docker-ce docker-ce-cli containerd.io
    
  • Start Docker:

      sudo service docker start
    
  • Recommended (Optional): Run Docker Without Sudo:

    If you use this command, you will no longer need to prepend sudo when using docker commands. Therefore, we will not use sudo for the rest of this article. But if you need to run service commands to alter or check the status of docker, you need sudo.

      sudo usermod -aG docker $USER
      newgrp docker
    

Post-Installation Steps

Now let's do just a few more things to spice it up. Let's check if we have some basic extensions installed.

Run docker and see if you get any warnings about invalid plugins just after the "commands" section. If you have missing plugins, you should see this output:

In order to resolve it, we need to install those plugins. Run the following commands based on the plugins you want:

Docker compose plugin

To download and install the plugin, run the following commands:

mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

The first command makes the directory that will house all plugins. The second downloads and installs it.

After this, we need to make it executable by changing its permissions. Run chmod +x ~/.docker/cli-plugins/docker-compose to do so.

Verify the installation using the name of the plugin. Run docker compose version. You should get output. Another way to check is by running docker again and ensuring that you no longer see a warning for that plugin. You will follow this step for the other plugins.

Docker Buildx plugin

curl -SL https://github.com/docker/buildx/releases/download/v0.10.5/buildx-v0.10.5.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
chmod +x ~/.docker/cli-plugins/docker-buildx

Again, we first install and then make the file executable as we did previously and also check to be sure it's installed properly by running docker buildx version .

Docker scan plugin

curl https://github.com/docker/scan-cli-plugin/releases/latest/download/docker-scan_linux_amd64 -L -s -S -o ~/.docker/cli-plugins/docker-scan
chmod +x ~/.docker/cli-plugins/docker-scan

Autostart Docker when WSL is launched

Now we need to make our life easier by automatically starting Docker whenever we open WSL. We don't want the stress of typing sudo service docker start every single time. For this step, we need to modify the home directory's shell configuration file. On my distro, there is a ~/.bashrc file that is fired whenever WSL is booted. If you don't see that file, look out for ~/.zshrc . If neither exists, create the appropriate one.

Head into the Nano editor using nano ~/.bashrc. If it does not work, you need to prepend sudo.

Add sudo service docker start > /dev/null to the file. This command boots up docker but also prevents the output from being sent to the terminal every time you boot. It makes use of Linux's null device. If you want the output, simply use sudo service docker start instead.

Now reboot the WSL distro to be sure it works even though we both know it will (I have trust issues. Must always double-check).

Finally, to check the status of Docker, run sudo service docker status.

(Optional) Add your plugins to PATH

Add the plugin directory to your PATH to ensure they are accessible. Run nano ~/.bashrc and add:

export PATH=$PATH:~/.docker/cli-plugins/

Add this line to your shell configuration file (e.g., ~/.bashrc or ~/.zshrc), then reload your shell configuration: source ~/.bashrc

Verifying Docker Installation

We can now run a simple Hello world program to make sure Docker works. In your terminal, run docker run hello-world.

If you get this output, you're good to go!

Conclusion

To wrap things up, we've covered the essential steps to ensure Docker runs smoothly on your WSL setup. From editing configuration files to adding necessary commands and verifying the installation, these steps help streamline your development environment. By following this guide, you can confidently manage Docker services and ensure they are always ready to go. Happy coding!