Running Java GUI application in Docker
This is a more specific use case of running GUI application with Docker, the procedure is pretty simple (and most option are common for most GUI application), You mount the UNIX socket for the display server, and define the `DISPLAY` variable, mount any necessary volumes you need the application to have access to, and if you need any unique network access define this as well.
In my use case, I need to run a GUI application to manage a remote DB in a isolated environment which can only be reached via VPN or ssh tunneling, and so I need the container to have access to a tunnel I create, and this is why I’m using the `host` network option.
First building the running container
FROM docker.io/java RUN /usr/sbin/useradd --comment Developer \ --home-dir /home/developer \ --non-unique --uid 1000 --user-group --system \ --shell /bin/bash developer && mkdir -p /home/developer RUN chown -R developer:developer /home/developer && mkdir -p /opt/app && chown -R developer:developer /opt/app RUN echo 'developer ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers USER developer ENV HOME /home/developer VOLUME /opt/app
build it with
docker build -t java-app - < /path/to/Dockerfile
and now we can set a small bash script to run the application for us,
#!/bin/bash CONTAINER='java-app' docker run -ti --rm \ -e _JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=lcd -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel' \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v /usr/share/fonts:/usr/share/fonts:ro \ -v /opt/DbVisualizer:/app \ -v /home/${USER}/.config/dbvis:/home/developer/.dbvis:z \ --security-opt label=type:container_runtime_t \ --network=host \ "${CONTAINER}" /app/dbvis
In the above example I’m using DbVisualizer as I wanted to test the application without contaminating my system with all the Java runtime requirements.
I also mount my local fonts folder to the container, as I like to use some mono fonts I have in my system, and also exporting few `JAVA_OPTIONS` to enable anti-aliasing and having a better interaction with my desktop environment.
Resources
- http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
- https://unix.stackexchange.com/questions/386767/selinux-and-docker-allow-access-to-x-unix-socket-in-tmp-x11-unix
- https://adam.younglogic.com/2017/01/gui-applications-container/
- https://wiki.archlinux.org/index.php/Java_Runtime_Environment_fonts
- https://docs.docker.com/network/host/