Running GUI apps in Docker

Josip Maslać, Javantura, 02/2017

Me

  • Josip Maslać

  • (java) developer

  • average GNU/Linux user

  • cofounder and owner of

nabava logo sova sa tekstom nabava net

Docker 101

  • open-source project that automates the deployment of applications inside software containers

container

virtual machines

transportable

Classic VMs

vm other

Docker

vm docker

lightweight & fast

Key terms

  • image

  • (image) registry

  • container

  • image ⇒ template for a container

  • OOP analogy: classes & objects

Demo

# docker <command> [options]
$ docker pull ubuntu	# docker hub (hub.docker.com)
$ docker images	# list all images

REPOSITORY   TAG      IMAGE ID     CREATED      SIZE
nabava/solr  latest  a53291b74a7c  5 weeks ago  1.03 GB
nabava/mysql latest  b3a5e0cb42b3  5 weeks ago  718.5 MB
nabava/java  latest  05608501f34b  5 weeks ago  808.2 MB
ubuntu       latest  104bec311bcd  3 weeks ago  128.9 MB
$ docker images | grep ubuntu

REPOSITORY   TAG      IMAGE ID     CREATED      SIZE
ubuntu       latest   104bec311bcd 3 weeks ago  128.9 MB
ubuntu       16.04    104bec311bcd 3 weeks ago  128.9 MB
ubuntu       14.04.5  ac192759f936 3 months ago 187.9 MB

Running containers

# docker run [options] <image> [command]
$ docker run ubuntu:16.04 echo "hello"
hello
$
$ docker ps	# list running containers

CONTAINER ID  IMAGE           COMMAND             CREATED     STATUS     PORTS                     NAMES
4802ebe8de68  nabava/haproxy  "bash /run.sh"      4 weeks ago Up 3 hours                           haproxy
03f60e3ba466  nabava/solr     "/bin/bash /run.sh" 5 weeks ago Up 4 hours                           solr
3a4c3321be1f  nabava/mysql    "/bin/bash run.sh"  5 weeks ago Up 4 hours 0.0.0.0:23306->3306/tcp   mysql
$ docker ps -a	# list all

CONTAINER ID  IMAGE           COMMAND             CREATED        STATUS                    PORTS                     NAMES
208651c624d5  ubuntu:16.04    "echo hello"        10 minutes ago Exited (0) 10 minutes ago                           naughty_lovelace
4802ebe8de68  nabava/haproxy  "bash /run.sh"      4 weeks ago    Up 3 hours                                          haproxy
03f60e3ba466  nabava/solr     "/bin/bash /run.sh" 5 weeks ago    Up 4 hours                                          solr
3a4c3321be1f  nabava/mysql    "/bin/bash run.sh"  5 weeks ago    Up 4 hours                0.0.0.0:23306->3306/tcp   mysql

container is alive if: ps ax | wc -l > 0

Creating images

Dockerfile

FROM ubuntu:16.04
MAINTAINER Josip Maslac <josip.maslac@nabava.net>

RUN apt-get update

RUN apt-get -y apache2
RUN apt-get -y libapache2-mod-php
ADD configuration /etc/myconfiguration

CMD ["/usr/sbin/apache2", "-DFOREGROUND"]
$ docker build -t <image_name> .
$ docker push <image_name>

Recap

docker image vs containers

One more thing

container volumes

# -v <host_folder>:<container_folder>
$ docker run -v /home/developer/mysql-data:/var/lib/mysql mysql

Why am I here?!

our situation

our situation

ideal: have the same setup in dev environment

My goal

./dev_env.sh developer_private_key
# dev_env.sh - something like:

docker login our.private.registry
docker run mysql
docker run some_service
docker run some_other_service
docker run webapp

Context

  • in a non java world

    docker run -v /home/developer/app:/srv/www/htdocs php-webapp
  • use (host) text editor for /home/developer/app

  • Java world:

    • Application containers (tomcat)

      • where your compiled (java) apps are running

    • IDEs (Eclipse)

      • tightly integrated with app containers

        • managing (start/stop, configure) && debugging

Possible solution

connect remotely to tomcat

eclipse tomcat remote

other stuff in our tomcat container (html2pdf, custom fonts etc.)

development environment <> production

(Our) solution

eclipse image

on top of tomcat image

eclipse in docker
$ docker run eclipse

Running GUI apps in docker

  • X Windows System (X11)

    • basic framework for a GUI environment

    • client-server

      • localhost (unix socket)

      • network

  • X server

    • sends graphics resources and keyboard/mouse events to X clients

X server architecture

x client server

Demo time

key part: /tmp/.X11-unix

# Dockerfile:
FROM nabava/tomcat-nabava
MAINTAINER Josip Maslac <josip.maslac@nabava.net>

RUN apt-get update

# download/install eclipse

...

Eclipse

$ docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix eclipse /bin/bash
root@208651c624d5:/# /eclipse/eclipse
Failed to connect to Mir: Failed to connect to server socket: No such file or directory
Unable to init server: Could not connect: Connection refused
Eclipse: Cannot open display:
...
root@208651c624d5:/# exit

$DISPLAY env variable

$ docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix eclipse /bin/bash
root@208651c624d5:/# /eclipse/eclipse
Failed to connect to Mir: Failed to connect to server socket: No such file or directory
Unable to init server: Could not connect: Connection refused
Eclipse: Cannot open display:
...
root@208651c624d5:/# exit
xhost +local:docker	# enable local docker containers to access X server

Recap

  • xhost +local:docker

  • -v /tmp/.X11-unix:/tmp/.X11-unix

  • -e DISPLAY=$DISPLAY

  • install graphic libraries

    • depending on the application(s) we want to run

Gotchas

process owner

$ docker run -it ubuntu whoami
root

Gotchas

  • file ownership & permissions

docker run -it -v /home/user/workspace:/workspace ... eclipse
# on the host
$ ls -ls /home/user
...
drwxr-xr-x  5 root  root  4096 Sij  3 12:28 workspace
...

Workaround

host - container start script
DEV_GROUP_ID=$( id -g )	# get current user group ID
DEV_USER_ID=$( id -u )	# get current user ID

docker run -e DEV_GROUP_ID -e DEV_USER_ID ... eclipse
Dockerfile - container initialization script
...
CMD ["/bin/bash","/run.sh"]
container - run.sh
groupadd -g $DEV_GROUP_ID users
useradd -g $DEV_GROUP_ID -u $DEV_USER_ID developer
...
chown -R developer:users /workspace
...
exec gosu developer /eclipse/./eclipse -data /home/developer/workspace

Gotchas

  • pasting

    • text - yes

    • files - no go

  • no "external" tools available

    • other then those installed in image/container

  • you cannot get "out of" a container

Alternative approaches

(to using X11 unix socket)

  • ssh + X11 forwarding (-X switch)

  • VNC

    • full desktop installed inside container

Windows?

doable!

  • Xming X Server for Windows

  • running ssh daemon inside a container

    • exposed on some port

  • putty to that container

    • ("X11 forwarding" checked)

    • start you GUI app

Windows

docker eclipse windows

Conclusion

  • minimum dev. environment setup time

  • dev = production

    • not 100% but close enough

  • learned someting new

    • and now talking about it

Thank you