/ core-os

How Do I Run a Java App with a GUI in Docker?

Docker is best suited for running services vs. applications that have GUIs. However, it is possible to run applications that have X11 based GUIs on Docker using x11vnc. It is a rather complex topic.

Let's start with the basics, HelloWorldSwing.java

mkdir apps
cat <<\EOF > apps/HelloWorldSwing.java
import javax.swing.*;        

public class HelloWorldSwing {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("<html><div style='font-size: 100pt'>Hello World</div></html>");
        label.putClientProperty("JComponent.sizeVariant", "large");
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
EOF

OK, we have a Java program. Now we need to compile it.

docker run -v$(pwd)/apps:/apps --name javac.app openjdk:7-jdk-alpine javac /apps/Hello/HelloWorldSwing.java

Now for the fun part. Let's bring up a Docker container running x11vnc and Java 8. We'll use Java 8 from Azul Systems vs. OpenJDK.

First we need to create some files:

mkdir profile.d
cat <<\EOF > profile.d/javac.sh 
#!/bin/sh

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin:/usr/lib/jvm/zulu-8-amd64/jre/bin
EOF
cat <<\EOF > xsession
#!/bin/bash
# ~/.Xclients, start my programs.

xterm -ls -geometry 190x70+80+30 &

echo Starting Window Manager...

exec lwm >> ~/.lwm-errors 2>&1

# eof
EOF
cat <<\EOF > Dockerfile
FROM debian:jessie-slim

RUN     apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0x219BD9C9
RUN     echo "deb http://repos.azulsystems.com/debian stable  main" >> /etc/apt/sources.list.d/zulu.list
RUN     apt-get -qq update
RUN	apt-get install -y vim net-tools netcat
RUN	apt-get install -y x11vnc xvfb
RUN	apt-get install -y lwm
RUN	apt-get -yq install zulu-8; true

RUN	mkdir /root/.vnc

COPY	xsession /root/.xsession
RUN	chmod +x /root/.xsession

ADD	profile.d /etc/profile.d

EXPOSE  5900
EOF
cat <<\EOF > rungui 
#!/bin/bash
docker build -t debian:gui --build-arg REBUILD=${RANDOM} . 2>&1 | tee build.out

#docker rm -f gui.app
docker run -d -p 3000:3000 -p 3000:3000/udp -p 5900:5900 -v$(pwd)/apps:/root/apps --name gui.app debian:gui init
docker exec -it gui.app su - -c 'x11vnc -forever -nopw -create'
EOF
chmod +x rungui

Let's start the Docker container where the app lives:

./rungui

We'll need a VNC viewer. I like this one:

http://tigervnc.org/

For testing, we can just disable all the security and passwords in the VNC viewer. Then connect to the Docker container. Note: you must use the IP address of the host running the Docker engine. If this is a VM, the network interface must be bridged or port forwarding of 5900 must be used.

At this point you will have a shell running in an xterm. Just execute the program using the java command:

cd apps/Hello
java HelloWorldSwing
How Do I Run a Java App with a GUI in Docker?
Share this