Building a dockerized GUI by sharing the host screen with docker container

Few months ago, I decided to build my own smart mirror using a Raspberry Pi 4 (I will share that experience later). But I wanted to build the software I wanted to use for the smart mirror before ordering my raspberry pi.

My technology choice went to Python3, using the TK library for python to build the GUI. I also wanted to dockerize the application for easier development. But problem: TK requires a display to work, and the python docker container I am using does only have a command line interface.

After few research and trying different solutions, I manage to have a definitive solution.

Procedure to share a display with a docker container on macOS Catalina

Using a MacBook Pro and macOS Catalina, here is what I found:

  1. Download Xquartz (https://www.xquartz.org) & install it
    When installed, run the software and make sure to select in the
    xQuartz > preferences > Security
    the option “Allow connections from network” should be checked.
  2. Allow your screen to be shared with local environment running on your laptop
    By simply typing in a terminal: `xhost +127.0.0.1`. The output “127.0.0.1 being added to access control list” should be displayed if everything went well. That command has to be run every time you stop the application xQuartz on your laptop.
  3. Share the screen with your docker container running
    It is where it is a bit tricky. Here is how you have to run your docker container in order to share the laptop screen to the application running in docker:
docker run -i -t - rm -e DISPLAY=host.docker.internal:0 -v /tmp/.X11-unix:/tmp/.X11-unix:ro - name="my_container_name" namespace/container

Some explanation:
-e DISPLAY => we create an environmental variable named DISPLAY in the container and value will be the host machine IP (your laptop, on Mac it should always be host.docker.internal) and the number identifying the screen (if you don’t have 2 screens, it should be 0. If you are having multiple screens, you will have to figure out the number of the screen.

-v /tmp/.X11-unix:/tmp/.X11-unix:ro => sharing the X11 information about the screen in read-only mode.

And that’s it, the rest is pretty similar to what we use on a normal docker environment. The docker container will be killed as soon as the application stops running. In my case with python TK, as soon as I close the GUI, the docker-container stops and get removed.

Conclusion

I am always impressed by what we can do with docker. It is indeed very useful for backend development, but it can be used in different context, and using that trick, you can actually run softwares inside a docker container instead of actually installing anything on your laptop.

The downside is actually it is not straightforward to share a display, it is actually not necessarily advised to allow display to be shared with third party software and would also only do that in development mode. In the actual running system, just run the program using the python3 command line on the system itself.

Raphaël Gonçalves

Written by

PHP Developer at Spectrm — Zend PHP Certified Engineer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade