Skip to content

Instantly share code, notes, and snippets.

@jwilson8767
Last active May 14, 2020 17:17
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save jwilson8767/00a46f5ca63327d5bfd802f87b702c8d to your computer and use it in GitHub Desktop.
Save jwilson8767/00a46f5ca63327d5bfd802f87b702c8d to your computer and use it in GitHub Desktop.
Docker Toolbox for Windows and Windows Subsystem for Linux (aka Bash on Windows)
#
# This script installs and configures WSL to work with Docker Toolbox for Windows.
# 1. Install WSL (check out [bowinstaller](https://github.com/xezpeleta/bowinstaller) for programmatic installation.
# 2. Run the contents of this script in Bash. (copy and paste works fine, no need to save)
#
sudo -sEH << 'EOM'
# Install the docker client and docker-compose
apt-get update && apt-get install -y curl ca-certificates
curl -sSL https://get.docker.com/ | sh
curl -L "https://github.com/docker/compose/releases/download/1.11.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Add the current user to the docker group.
usermod -aG docker $(id -un)
# Symlink /c/ to /mnt/c/ as Docker Toolbox is expects /c/ path mappings.
[[ ! -e /c/ ]] && ln -s /mnt/c /
EOM
#Set docker-machine to run on terminal start.
cat >> ~/.bashrc << 'EOM'
# Start the docker machine
export VBOX_MSI_INSTALL_PATH='/c/Program Files/Oracle/VirtualBox/'
pushd '/c/Program Files/Docker Toolbox/' > /dev/null
./start.sh exit
# Get env variables from docker-machine, convert paths, ignore comments, and strip double quotes.
$(./docker-machine.exe env --shell bash | sed 's/C:/\/c/' | sed 's/\\/\//g' | sed 's:#.*$::g' | sed 's/"//g' )
popd > /dev/null
# Change /mnt/c/ to /c/ in current working directory path
cd $(pwd | sed 's/\/mnt\/c\//\/c\//')
EOM
@jwilson8767
Copy link
Author

This may not work for WSL prior to the creators update (requires windows interop).

@jwilson8767
Copy link
Author

I believe this could be modified for Docker for Windows, I just don't have a machine to test on.

Copy link

ghost commented Aug 8, 2017

seems to be working in windows version 1703 (OS Build 15063.502), However docker-machine command is not found... not sure why

@jwilson8767
Copy link
Author

@andrewlozoya Can you verify that C:\Program Files\Docker Toolbox\docker-machine.exe exists?

@EzeRangel
Copy link

The commands are recognized in the WSL but do nohing.

@jwilson8767
Copy link
Author

@EzeRangel, what do you mean by "the commands" and "do nothing". After running this are you able to run operations like docker ps?

@jwilson8767
Copy link
Author

@EzeRangel, I just realized that I had omitted a critical part of matching up WSL to work with Docker Toolbox for Windows. I have now added that part (lines 27 and 28) and this will hopefully work for you now.

@jwilson8767
Copy link
Author

Does anyone have an idea how to package this to better be distributed? Could we somehow wrap the docker command in WSL to automatically start docker-machine if it's not already running? Could we distribute via a single command like 'curl https://thisscript.sh | bash'? How can we avoid cluttering .bashrc?

@agocorona
Copy link

agocorona commented Aug 30, 2017

Works well. Thanks

@rrbutani
Copy link

The docker-machine + sed command (line 25) to grab and set variable seems to break on User directory names that have spaces. This monstrosity (below) seems to handle spaces better, but I'm sure there's a better way to do it.

arr=$(./docker-machine.exe env --shell bash | sed 's/C:/\/c/' | sed 's/\\/\//g' | sed 's:#.*$::g' | sed 's/"/\x27/g')
readarray -t y <<<"$arr"
for ((i=0; i< ${#y[@]}; i++)); do eval "${y[$i]}"; done

@fishnux
Copy link

fishnux commented Oct 12, 2017

For some reason, when I use docker-compose, mounted volumes start with path "/mnt/c/", instead of "/c/", causing the volume to be improperly mounted (I think). Does anyone know a fix for this?

Here's my docker-compose.yml:

web:
    image: nginx:latest
    ports:
        - "8080:80"
    volumes:
        - ./code:/code
        - ./site.conf:/etc/nginx/conf.d/site.conf
web_1  | 2017/10/12 13:17:08 [crit] 1#1: pread() "/etc/nginx/conf.d/site.conf" failed (21: Is a directory)
web_1  | nginx: [crit] pread() "/etc/nginx/conf.d/site.conf" failed (21: Is a directory)

When using PowerShell, everything works fine.

@schenkj
Copy link

schenkj commented Oct 25, 2017

Getting
Could not read CA certificate "/home/schenkj/.docker/ca.pem": open /home/schenkj/.docker/ca.pem: no such file or directory when running docker ps on WSL.

@jwsloan
Copy link

jwsloan commented Nov 19, 2017

This is great! This might be a newb question, but how do I handle this?

$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Update... I'm now up and running thanks to this script as well as this gist, and possibly another link I can't find right now.

I think these are all the steps that got me the rest of the way:

I added these to .bashrc (.zshrc in my case):

export DOCKER_TLS_VERIFY=0                                         
export DOCKER_HOST=tcp://$(cd /mnt/c && docker-machine.exe ip):2376

Then back in my terminal I ran these commands:

docker-machine.exe restart default
mkdir -p ~/.docker
ln -s /mnt/c/Users/John/.docker/machine/certs/ca.pem ~/.docker/ca.pem
ln -s /mnt/c/Users/John/.docker/machine/certs/ca-key.pem ~/.docker/ca-key.pem
ln -s /mnt/c/Users/John/.docker/machine/certs/cert.pem ~/.docker/cert.pem
ln -s /mnt/c/Users/John/.docker/machine/certs/key.pem ~/.docker/key.pem
docker-machine.exe upgrade

Finally I followed these instructions to get my DNS setup to use google's 8.8.8.8 and 8.8.8.4.

@strarsis
Copy link

strarsis commented Jan 16, 2018

There is a nice docker-env wrapper script that does the ENV/export conversion (well enough, had no issues yet):
https://gist.github.com/mmarchini/bc9df7b82127fea13612edf8bffdf96f

I made a similar HOWTO (though inferior to this approach I think), maybe it is still helpful for you for fixing some other issues:
https://gist.github.com/strarsis/44ded0d254066d9cb125ebbb04650d6c

@austinkelleher
Copy link

austinkelleher commented Feb 1, 2018

I am also having trouble with volumes. The files are missing when using docker-compose up. Example:

version: '3'
services:
  myservice:
    image: some/image
    build .
    volumes:
     - .:/usr/my-service
     - /usr/my-service/node_modules

Example Dockerfile:

FROM node:8.9.4-alpine

ENV HOME=/usr/my-service
RUN mkdir -p $HOME
WORKDIR $HOME

ADD package.json $HOME
ADD package-lock.json $HOME

RUN npm install --silent

ADD . $HOME

EXPOSE 8080

CMD npm run start:docker

Any ideas? /cc @fishnux @strarsis @jwilson8767

@schindld
Copy link

A recent commit in docker toolbox breaks this. Two changes in this commit are problematic.

  1. They no longer hard-code the docker toolbox and docker-machine.exe paths. Simple fix is to do export DOCKER_TOOLBOX_INSTALL_PATH='/c/Program Files/Docker Toolbox' before calling ./start.sh exit.
  2. On line 80 of the commit, they convert the exports to SETX syntax, which won't work in wsl. Not sure of a good fix for this. Personally, I just deleted the line from my start.sh, but I'd rather have a fix in my .bashrc without touching start.sh.

@carlin-q-scott
Copy link

Unfortunately, start.sh uses a windows path to docker-machine.exe. I fixed it locally to use which to find the executable but then that exposed another issue: you cannot run docker-machine.exe commands without the variables set by docker-machine.exe --shell bash. So you can't run the command that sets the variables that you need to run the command.

@sabarnix
Copy link

source <(docker-machine.exe env default --shell bash | sed 's?\\?/?g;s?C:/?/mnt/c/?g') run this before docker-compose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment