Search code examples
pythondockeruser-interfacexserverwxpython

is $DISPLAY set properly? - Running a wxPython Phoenix GUI in a docker container


I would like to dockerize a GUI written with wxPython Phoenix in order to have the GUI appear on the host when running the docker image.

Below is a basic wxPython Phoenix GUI and the Dockerfile that creates an image with Ubuntu 18.04, Python 3.7.5 and wxPython Phoenix.

When running the image, it returns the following message:

docker build -t simple-gui:latest .
docker run -it simple-gui /bin/bash
root@97229a17f2cd:~/python# ./simple_gui.py
Unable to access the X Display, is $DISPLAY set properly?

I understand I have to send the address of the host's X server to the docker image that would then be used by wxPython Phoenix, but I'm not sure how to do that.

simple-gui.py: (from wxPython Phoenix wiki)

#!/usr/bin/env python3.7

import wx

app = wx.App(False)
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)
app.MainLoop()

Dockerfile:

FROM ubuntu:18.04

# Install dependencies for Python and wxPython Phoenix
RUN apt update && apt install -y \
    libwebkitgtk-3.0-dev \
    libgtk-3-dev \
    libsm-dev \
    freeglut3 \
    freeglut3-dev \
    libnotify-dev \
    libgstreamer1.0-dev \
    libgstreamer-plugins-base1.0-dev \
    dpkg-dev \
    build-essential \
    python3.7-dev \
    libjpeg-dev \
    libtiff-dev \
    libsdl1.2-dev \
    software-properties-common \
# Install Python 3.7 and pip latest versions
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt install -y python3.7 python3-pip \
    && python3.7 -m pip install -U --no-cache-dir pip \
# Install wx
    && python3.7 -m pip install -U --no-cache-dir -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 wxPython

# Copy files
COPY simple_gui.py /root/python/
WORKDIR /root/python
ENTRYPOINT ["./simple_gui.py"]

Solution

  • As said in the question, the DISPLAY variable is used in the docker image to store the host's X server address. Depending on the host, it should take different values.

    UNIX host (Linux/MacOS):

    UNIX already uses an X server for display purposes.

    1. Set a DISPLAY variable such as DISPLAY=:0.0.
    2. Run your image with: docker run -e DISPLAY=$DISPLAY simple-gui

    Windows host:

    Windows does not use an X server but Windows Desktop Manager.

    1. You need to install an X server for Windows, a popular choice is VcXsrv.
    2. Set a DISPLAY variable to DISPLAY=<HOST_IP>:0.0, the value for <HOST_IP> can be found using ipconfig, it's the one tagged DockerNAT.
    3. Run your image with: docker run -e DISPLAY=$DISPLAY simple-gui (or DISPLAY=%DISPLAY%, depending on your command line...)

    Sources: