Docker on WSL for Windows 10

Configure Docker for Windows

In the general settings, you’ll want to expose the daemon without TLS. This step is necessary so that the daemon listens on a TCP endpoint. If you don’t do this then you won’t be able to connect from WSL.

blog/docker-for-windows-expose-daemon-without-tls.jpg

You may also want to share any drives you plan on having your source code reside on. This step isn’t necessary but I keep my code on a regular HDD, so I shared my “E” drive too.

Can’t use Docker for Windows?

This is only necessary if you are NOT running Docker for Windows!

No problem, just configure your Docker daemon to use -H tcp://0.0.0.0:2375 and --tlsverify=false. Then you can follow along with the rest of this guide exactly.

 

Here’s the Ubuntu 16 installation notes taken from Docker’s documentation:

This will install the edge channel, change ‘edge’ to ‘stable’ if you want. You may also want to update the Docker Compose version based on the latest release.

# Environment variables you need to set so you don't have to edit the script below.
export DOCKER_CHANNEL=edge
export DOCKER_COMPOSE_VERSION=1.21.0

# Update the apt package index.
sudo apt-get update

# Install packages to allow apt to use a repository over HTTPS.
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 -

# Verify the fingerprint.
sudo apt-key fingerprint 0EBFCD88

# Pick the release channel.
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   ${DOCKER_CHANNEL}"

# Update the apt package index.
sudo apt-get update

# Install the latest version of Docker CE.
sudo apt-get install -y docker-ce

# Allow your user to access the Docker CLI without needing root.
sudo usermod -aG docker $USER

# Install Docker Compose.
sudo curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose &&
sudo chmod +x /usr/local/bin/docker-compose

At this point you must close your terminal and open a new one so that you can run Docker without sudo. You might as well do it now!

Configure WSL to Connect to Docker for Windows

The next step is to configure WSL so that it knows how to connect to the remote Docker daemon running in Docker for Windows (remember, it’s listening on port 2375).

Open up your ~/.bashrc file and add this line to the bottom:

export DOCKER_HOST=tcp://0.0.0.0:2375

Logout of your WSL shell and come back in, or run source ~/.bashrc to reload it now.

If you want to get cute, you could do all of that with this 1 liner:

echo "export DOCKER_HOST=tcp://0.0.0.0:2375" >> ~/.bashrc && source ~/.bashrc

You can verify it works by running docker info. You should get back a list of details. If you get a permission denied error then make sure you log out and log back in, because that’s necessary to apply the changes so non-root users can run Docker. That’s what the sudo usermod bit of the long command did in the command chain when installing Docker.

Ensure Volume Mounts Work

The last thing we need to do is set things up so that volume mounts work. This tripped me up for a while because check this out…

When using WSL, Docker for Windows expects you to supply your volume paths in a format that matches this: /c/Users/bcochran/dev/myapp.

But, WSL doesn’t work like that. Instead, it uses the /mnt/c/Users/bcochran/dev/myapp format.

To get things to work for now, you need to bind a custom mount for any drives that you shared with Docker for Windows.

Bind custom mount points to fix Docker for Windows and WSL differences:
sudo mkdir /c
sudo mount --bind /mnt/c /c

You’ll want to repeat those commands for any drives that you shared, such as d or e, etc..

Verify that it works by running: ls -la /c. You should see the same exact output as running ls -la /mnt/cbecause /mnt/c is mounted to /c.

You can use volume mount paths like .:/myapp in your Docker Compose files and everything will work like normal. That’s awesome because that format is what native Linux and MacOS users also use.

It’s worth noting that whenever you run a docker-compose up, you’ll want to make sure you navigate to the /c/Users/bcochran/dev/myapp location first, otherwise your volume won’t work. In other words, never access /mnt/cdirectly.

 

Automatically set up the bind mount:

 

You can do that with this 1 liner: echo "sudo mount --bind /mnt/c /c" >> ~/.bashrc && source ~/.bashrc and make sure to repeat the command for any additional drives you shared with Docker for Windows. By the way, you don’t need to mkdir because we already did it.

Allow your user to bind a mount without a root password:

To do that, run the sudo visudo command.

That should open up nano (a text editor). Goto the bottom of the file and add this line: bcochran ALL=(root) NOPASSWD: /bin/mount, but replace “bcochran” with your username.

That just allows your user to execute the sudo mount command without having to supply a password. You can save the file with CTRL+O, confirm and exit with CTRL+X.

Installing Docker on Ubuntu

To install Docker CE, you need the 64-bit version of one of these Ubuntu versions:

  • Zesty 17.04
  • Xenial 16.04 (LTS)
  • Trusty 14.04 (LTS)

SET UP THE REPOSITORY

  1. Update the apt package index:
    $ sudo apt-get update
    
  2. Install packages to allow apt to use a repository over HTTPS:
    $ sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        software-properties-common
    
  3. Add Docker’s official GPG key:
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    

    Verify that you now have the key with the fingerprint9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, by searching for the last 8 characters of the fingerprint.

    $ sudo apt-key fingerprint 0EBFCD88
    
    pub   4096R/0EBFCD88 2017-02-22
          Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
    uid                  Docker Release (CE deb) <docker@docker.com>
    sub   4096R/F273FCD8 2017-02-22
    
  4. Use the following command to set up the stablerepository. You always need the stable repository, even if you want to install builds from the edge or testrepositories as well. To add the edge or test repository, add the word edge or test (or both) after the word stable in the commands below.

    Note: The lsb_release -cs sub-command below returns the name of your Ubuntu distribution, such as xenial. Sometimes, in a distribution like Linux Mint, you might have to change $(lsb_release -cs) to your parent Ubuntu distribution. For example, if you are usingLinux Mint Rafaela, you could use trusty.

    amd64:

    $ sudo add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
       $(lsb_release -cs) \
       stable"

    INSTALL DOCKER CE

    1. Update the apt package index.
      $ sudo apt-get update
      
    2. Install the latest version of Docker CE, or go to the next step to install a specific version. Any existing installation of Docker is replaced.
      $ sudo apt-get install docker-ce

      Configure Docker to start on boot

      Most current Linux distributions (RHEL, CentOS, Fedora, Ubuntu 16.04 and higher) use systemd to manage which services start when the system boots. Ubuntu 14.10 and below use upstart.

      systemd

      $ sudo systemctl enable docker
      

      To disable this behavior, use disable instead.

      $ sudo systemctl disable docker
      

      If you need to add an HTTP Proxy, set a different directory or partition for the Docker runtime files, or make other customizations, see customize your systemd Docker daemon options.

      upstart

      Docker is automatically configured to start on boot usingupstart. To disable this behavior, use the following command:

      $ echo manual | sudo tee /etc/init/docker.override
      

      chkconfig

      $ sudo chkconfig docker on