Connect the webcam to Docker on Mac or Windows

Jongmin Park
7 min readJul 27, 2019

--

This story is based on here which is written in Korean.

To connect webcams to a docker container on macOS or Windows is not a frequently used job, but sometimes happen to need this work. I could not find the best solution that is why I started a long journey to search for a way to solve this problem. Finally, I can introduce this tutorial even if it is somewhat complicated.

Introduction

There are lots of good tutorials with open source project if you search at GitHub. Computer Vision, which is my interesting filed, is mostly recommended to use Ubuntu environment.

If I train or predict a data like a machine learning project, I could work on my Linux machine or using GCP. That occurs, however, a problem if I should print out images or videos for a test. Because of that I usually write codes using my Macbook Pro, and sometimes work in outside of the office. I prefer to use Docker for checking a visual result on my local laptop, also I ought to share my result with my teammate.

Problem

If my team want to review my work which is used a webcam (or camera) with a docker container on Mac or Windows, maybe they will input a docker command like docker run --device=/dev/video0:/dev/video0 ... . As you know, macOS and Windows do not have the path: /dev/video0, then the OS will alert an error. Moreover, it is a too hard mission that finds well-described solutions.

Should I change my Macbook Pro to Linux OS laptop? Maybe Windows laptop can do if it uses a method of dual OS boot system. But, that is not a perfect work to solve this problem.

Although my suggestion must follow troublesome setup steps, you can connect a webcam to docker on macOS or Windows. 🤓

macOS

First of all, you need to install Docker Desktop for Mac, VirtualBox, and VirtualBox Extension. Also,socat1 and xquartz2 are required like below (I recommend to use the terminal):

brew install socat
brew install xquartz

After that, run a below code line: XQuartz, it will pop a new terminal session. I assume that this new terminal session called Terminal 2 (or T2), the previous used terminal session called Terminal 1 (or T1).

open -a XQuartz

Next, check the XQuartz Preference and change like below:

XQuartz Preference

Run again a below code line on Terminal 1:

defaults write org.macosforge.xquartz.X11 enable_iglx -bool true

Define the environment values on Terminal 1, such as your docker-machine name if you want like below:

IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost + $IP

# name of docker-machine, possible to change the name if you want
DOCKER_MACHINE=webcam # (default) DOCKER_MACHINE=default

Basically, Docker Desktop for Mac does not need the VirtualBox, but this tutorial will create a virtual machine using by VirtualBox. Please run the next script on Terminal 1.

It will take a few minutes (depends on your network connection) due to download boot2docker.iso file. After finishing the job, check a list of the virtual machine using docker-machine ls and confirm your docker-machine name. For set up the virtual machine image, stop your docker-machine like below:

docker-machine stop ${DOCKER_MACHINE}

Check here what I changed boot2docker.iso file compared to the original.

After stopping your docker-machine, follow next images on VirtualBox.

Something value can be different, such as memory etc.

VirtualBox
Display tab on VirtualBox
Ports tab on VirtualBox
Shared Folders tab on VirtualBox

At last, you have done the pre-requisite setting. Following the next steps every time when you want to connect a webcam to a docker container.

  1. T1 open -a XQuartz
  2. T2 socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" if you have an error, check lsof -i tcp:6000 and kill the PID
  3. T1 IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
  4. T1 xhost + $IP
  5. T1 DOCKER_MACHINE=webcam or DOCKER_MACHINE=default
  6. T1 docker-machine start ${DOCKER_MACHINE}
  7. T1 eval $(docker-machine env ${DOCKER_MACHINE})
  8. T1 vboxmanage list webcams check a list
  9. T1 vboxmanage controlvm "${DOCKER_MACHINE}" webcam attach .1 or other

Before a test with webcams, please check the XQuartz is running well like below:

# xeyes
docker run --rm -it -e DISPLAY=$IP:0 gns3/xeyes

# firefox
docker run --rm -it -e DISPLAY=$IP:0 -v /tmp/.X11-unix:/tmp/.X11-unix jess/firefox

Then, reference a below guideline if you want to connect a webcam to a docker container.

docker run --rm -it --device=/dev/video0:/dev/video0 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=$IP:0 \
YOUR_DOCKER_IMAGE

I test the dlib python example code, and connect my built-in webcam works very well!

dlib face detect example on MacOS

Windows

I will use the Docker Toolbox due to use Windows 10 Home on my machine, I am not sure that it works well on Pro or Enterprise version.

Unlike macOS, you need to install Docker Toolbox on Windows. Of course, you need to install VirtualBox, and VirtualBox Extension.

The Docker Toolbox is located in C:\Program Files\Docker Toolbox. Find Docker Quickstart Terminal on the start menu and run it. Then, a virtual machine whose name is default create automatically and this process take a long time.

Docker Quickstart Terminal

Unfortunately, the default virtual machine cannot connect webcams and you must create a new virtual machine. Using a name as default or something new, that is your choice.

  • Using a name: default
docker-machine stop default
docker-machine rm default
DOCKER_MACHINE=default
  • (recommend) Using a name: webcam
docker-machine stop default
# name of docker-machine, possible to change the name if you want
DOCKER_MACHINE=webcam

And run the next script for creating a new virtual machine.

Sometimes, the ACTIVE status of your new virtual machine is -, then you should change it to * with eval $(docker-machine env ${DOCKER_MACHINE}).

Change the status of the ACTIVE

The upper image is my local status, and I created new docker-machine whose name is webcam as you can see. You can find URL like 192.168.99.103, but this value depends on your local machine. Next script helps you to find your docker-machine URL.

docker-machine ls | grep ${DOCKER_MACHINE} | awk '{print $5}'
# tcp://192.168.99.103:2376

Now, please install the Xming, then you can find a path of it: C:\Program Files (x86)\Xming. Open the x0.hosts file as administrator and modify it like below:

Please use your own URL when you find the previous step.

localhost
192.168.99.103

After saving the change, run Xming.exe file.

docker-machine stop ${DOCKER_MACHINE}

As you can see, stop your docker-machine and set up a few at your virtual machine on VirtualBox like below:

Display tab on VirtualBox
USB tab on VirtualBox

At last, you have done the pre-requisite setting on Windows 10 Home. Following the next steps every time when you want to connect a webcam to a docker container.

  1. Run Docker Quickstart Terminal
  2. DOCKER_MACHINE=webcam or DOCKER_MACHINE=default
  3. docker-machine stop default , ignore 3 and 4 if the name is default
  4. docker-machine start ${DOCKER_MACHINE}
  5. eval $(docker-machine env ${DOCKER_MACHINE})
  6. "/c/Program Files/Oracle/VirtualBox/VBoxManage" list webcams
  7. "/c/Program Files/Oracle/VirtualBox/VBoxManage" controlvm "${DOCKER_MACHINE" webcam attach .1 or other (this is one line script)
  8. Run Xming

Like macOS, please check the Xming run well like below:

# xeyes
docker run --rm -it -e DISPLAY=192.168.99.1:0 gns3/xeyes

# firefox
docker run --rm -it -e DISPLAY=192.168.99.1:0 -v /tmp/.X11-unix:/tmp/.X11-unix jess/firefox

Then, reference a below guideline if you want to connect a webcam to a docker container.

docker run --rm -it --device=/dev/video0:/dev/video0 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=192.168.99.1:0 \
YOUR_DOCKER_IMAGE

I also test the dlib python example code, and connect my Logitec webcam. Unfortunately, I do not have any recording program for Windows. I captured a realtime camera screen.

dlib face detect example on Windows

Conclusion

Connect a webcam to a docker container on Mac or Windows is not the impossible mission. However, there are future problems because that boot2docker is not a stable version.

Nonetheless, this is an attractive solution using Docker.

Summary

Mac

  1. T1 open -a XQuartz
  2. T2 socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
  3. T1 IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
  4. T1 xhost + $IP
  5. T1 DOCKER_MACHINE=webcam or DOCKER_MACHINE=default
  6. T1 docker-machine start ${DOCKER_MACHINE}
  7. T1 eval $(docker-machine env ${DOCKER_MACHINE})
  8. T1 vboxmanage list webcams
  9. T1 vboxmanage controlvm "${DOCKER_MACHINE}" webcam attach .1 or other

Windows

  1. Run Docker Quickstart Terminal
  2. DOCKER_MACHINE=webcam or DOCKER_MACHINE=default
  3. docker-machine stop default , ignore 3 and 4 if the name is default
  4. docker-machine start ${DOCKER_MACHINE}
  5. eval $(docker-machine env ${DOCKER_MACHINE})
  6. "/c/Program Files/Oracle/VirtualBox/VBoxManage" list webcams
  7. "/c/Program Files/Oracle/VirtualBox/VBoxManage" controlvm "${DOCKER_MACHINE" webcam attach .1 or other

Reference

--

--