Running Docker containers on Bash on Windows

When the Windows Subsystem for Linux (WSL) – or, as most people even at Microsoft often refer to it – Bash on Ubuntu on Windows – was announced on Microsoft’s Build conference 2016, a world of new tools opened up to us Windows devs. Personally, I love being able to choose between PowerShell, Bash or plain old cmd when I want to script something. And it’s always bugged me that I couldn’t get Docker working from Bash on Windows – until now.

The original title of this post was “Running Docker from Bash on Windows”, but that would have been a slight overstatement. Docker requires access to quite a of lot system calls which aren’t necessarily all implemented on Windows, so getting the engine running under the WSL is probably not so easy. Instead, we’ll run the Docker Engine on Windows, and connect to it from Bash. This also has the advantage that you can start a container from PowerShell and interact with it from Bash, or the other way around – in other words, your computer will still feel just like one machine.

Here’s how to do it:

1. Install Docker on Windows

To install the Docker engine on Windows, just go to docker.com and download the appropriate distribution. Also, make sure hardware virtualization is enabled and Hyper-V is installed, lest the engine won’t start.

Shortcut: Install Windows 10 Creators Update

With Windows 10 Creators Update*, accomplishing all of this has become a lot simpler, since it allows you to run Windows executables from Bash. Just add these two lines to your .bashrc and you’re done!

You can now run docker --version from Bash, and you don’t even have to read the rest of this blog post :)

*) Windows 10 Creators Update is available to Insiders since April 11, 2017, and will be released to the public on April 25, 2017.

Making it work on Windows 10 Anniversary Edition

To install Docker on the WSL, you’ll need to jump through a few more hoops. There’s a description for Ubuntu in general here, which works for the WSL as well, with the exceptions of some of the optional steps. Here’s what I did:

Of course, there’s also the option of downloading and extracting the binaries we’ll need, and put them somewhere in your PATH. There are instructions here for how to get the latest version.

Where did that get us?

We now actually have the Docker engine installed on both Windows and the WSL, but it isn’t started on either. The Windows installer helpfully created a Docker shortcut on the desktop and/or in the Start menu – use that to start the Docker engine. Then, you can try running e.g. docker images from PowerShell and from Bash:

PowerShell:

We haven’t created any images yet, so that’s fine.

Bash:

Clearly unsatisfying. But with one or two extra steps, we’ll get it all working.

2. Connect Docker on WSL to Docker on Windows

Running docker against an engine on a different machine is actually quite easy, as Docker can expose a TCP endpoint which the CLI can attach to.

Note: In an update to Docker that was pushed shortly after first publishing this post, this TCP endpoint is turned off by default (thanks Mark for the heads-up!); to activate it, right-click the Docker icon in your taskbar and choose Settings, and tick the box next to “Expose daemon on tcp://localhost:2375 without TLS” (make sure you understand the risks).

With that done, all we need to do is instruct the CLI under Bash to connect to the engine running under Windows instead of to the non-existing engine running under Bash, like this:

Much better!

There are two ways to make this permanent – either add an alias for the above command, or better yet (thanks Dave!), export an environment variable which instructs Docker where to find the host engine:

Now, running docker commands from Bash works just like they’re supposed to.
Mission accomplished!


The versions used in this post

Of course, things like these might always have dependencies of the versions of the tools you’re using. In this blog post, I’ve been using the following versions:

Windows
Windows 10 Pro Anniversary Edition (Version 1607, OS Build 14393.1066)
Windows 10 Pro Creators Update (Version 1703, OS Build 15063.138)
WSL Ubuntu
14.04.5 LTS
Docker on Windows
17.03.1-ce, build c6d412e
Docker on Ubuntu
17.03.1-ce, build c6d412e

14 Comments

  1. Hi !

    Thank you for your update with windows Creator’s update, but I would just add something, WSL can launch windows executables but you have to provide the extension, so to launch docker you would have to type docker.exe which is not very practical.

    Just add aliases for docker.exe and docker-compose.exe and you’re done :)

  2. Steinar Flatland

    Worked perfectly. Great stuff. Thank you!

  3. Dave C.

    Instead of
    echo “alias docker=’docker -H tcp://0.0.0.0:2375′” >> ~/.bashrc

    Do
    echo “export DOCKER_HOST=”tcp://0.0.0.0:2375” >> ~/.bashrc

    And regarding Romain Prevost’s alias suggestion: I’ve run into some issues using docker-compose with this setup. I found it easier to install docker-ce and docker-compose under WSL then just exporting the variable above.

  4. Great blog, I could successfully install Docker on windows.

  5. Mark C

    Trying this on May 15, 2017, using docker version 17.03.1-ce-win12 (12058), between parts 2 and 3 it was also necessary to select the following option from Docker > Settings > General:
    “Expose daemon on tcp://localhost:2375 without TLS”.
    Note the warning underneath that option, in case it is important to you:
    “Exposing daemon to TCP without TLS helps legacy clients connect to teh daemon. It also makes yourself vulnerable to remote code execution attacks. Use with caution.”

    Without doing that, you continue to get the connection error, “Cannot connect to the Docker daemon…”

    • Tomas Lycken

      I realized this would probably be necessary when I read the release note about this update, but I hadn’t had time to experiment with it and come up with a solution. Thanks for posting back here!

      • Leo

        Hey Guys,
        I wrote a small script, that gets loaded in bashrc, it mounts /mnt/c to /c so you can do host mounts, and it also creates an alias for docker-machine to generate the right docker-machine env exports, including the secured port and certs path. Can you guys try it out see if it’s useful ?
        https://github.com/leohinojosa/wsldocker
        thanks!

  6. Ronny Carlansson

    A very good thread! Been searching for this a while :)
    Had the same problem as Mark C – “Expose daemon on tcp://localhost:2375 without TLS”.
    Took a while before I read his comment…

    Best,

    • Tomas Lycken

      Glad you found it helpful!

      I’ve updated the post to make this point clearer; hopefully future readers won’t have to stumble on this.

  7. Peter

    Thanks for the really great article by the way.
    Looked like a very simple few steps to install docker, however I ran into a few issues.
    I have windows 10 creator update installed on my machine. However I only have the Home edition and therefore cannot install the windows version docker. I instead followed your instructions to install docker on WSL.
    I have set the DOCKER_HOST variable.
    However when I try and run docker ps I get the following error:
    Cannot connect to the Docker daemon at tcp://0.0.0.0:2375. Is the docker daemon running?
    If this is an issue with the TCP endpoint being turned off then how would I solve this without having docker installed on Windows?

  8. Leo

    The Creators Update approach works great! But as Romain Prevost mentioned I had to locate the program with docker.exe or docker-compose.exe instead.

    Also I was cloning my repositories into the Linux filesystem, which causes a warning about “Unable to translate current working directory. Using C:\WINDOWS\system32” because your windows programs cannot open Linux files. It’s a WSL limitation, but I really think it should just error out instead of giving a warning.

  9. Adrian

    I installed docker under WSL as you had it, and this worked fine, running the Docker engine installed under Windows. Wanting to remove the WSL installation and just run the Windows Docker from Bash with just the path additions you mentioned (when running the CU), I tried to “sudo apt remove docker-ce”, but this results in an error, and the package is not removed. Can you confirm that you also can’t remove the docker-ce package and that something gets borked when installing Docker under WSL?

  10. Karl

    Working with Windows 10 Home, Creator’s Update, WSL, Docker Toolkit.

Leave a Reply