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/