Vagrant, Docker, VirtualBox and the Graphical Desktop for GUI applications in Docker Containers docker vagrant gui2

Vagrant, Docker, VirtualBox and the Graphical Desktop for GUI applications in Docker Containers

Although perhaps not a common occurrence, I would still like to be able to sometimes run GUI applications inside a Docker container. This may be required because an installer does not provide a silent option and has a GUI wizard I need to click my way through in order to set up the software that the container subsequently will run. It can also be because my development environment management is fully containerized, including management of IDEs and other graphical development tools. Whatever the motivation for running GUI in containers – it is my topic in this article. More specifically: running GUI applications in Docker containers that are managed Vagrant – a combination I have discussed in several earlier articles (First steps with provisioning of Docker containers using Vagrant as provider and Vagrant and Docker – Next and Advanced steps with folders, ports, volumes, linking and more).

Note: I am using Vagrant 1.7.4 and Oracle VirtualBox 4.3.18. (VirtualBox 5.0 apparently has interesting support for remote desktop and GUI on headless servers so that is one of my next explorations).

The steps in this case:

  • Use Vagrant to provision a Docker container inside a Docker Host VM based on Ubuntu; this Docker container is set up with X-libraries
  • Add a Desktop to the Docker Host VM: sudo apt-get install –no-install-recommends lubuntu-desktop
  • Connect into the Docker container to use Puppet to provision a GUI application (in this case simply the Java JDK/JRE); commit the container and create a new image
  • Halt Docker Host VM through Vagrant
  • Start Docker Host VM through VirtualBox GUI – this will launch the GUI
  • Login into Ubuntu Desktop, start a terminal session and launch a Docker container for the new Docker image using special options: -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix
  • Run GUI application inside Docker Container

docker-vagrant-gui

Note: at this point, Vagrant cannot access the Docker Host VM to control the Docker Container or provision new ones. Only when the Docker Host VM is stopped through the VirtualBox GUI can we once again work with the Docker Host VM and the containers inside through Vagrant. This is an unpleasant consequence – although primarily problematic when provisioning containers, not so much when running them. I hope to find a way to start Docker Host VM from Vagrant and somehow connect to the desktop through RDP or perhaps using new VirtualBox 5.0 features.

All sources – Vagrant, Docker and Puppet – can be found in GitHub: https://github.com/lucasjellema/vagrant-docker-puppet-desktop.

And Action

The starting point – as cloned from the Git repository – looks as follows:

image

Note that the files directory contains the Java installation files jdk-7u79-linux-x64.tar and UnlimitedJCEPolicyJDK7.zip.

Use Vagrant to provision a Docker container inside a Docker Host VM based on Ubuntu. Note that this Docker container is set up with X-libraries.

image

First, Vagrant will work on creating the Docker Host vm called dockerdesktophostvm.

Next, the Docker Container my-desktop-base-container is provisioned. This container is set up – as is specified in the Dockerfile – with Puppet and with the X-libraries required for GUI action (as the next figure shows).

image

After some (ample) time, the container is created:

image

 

Vagrant global-status shows both the container and the Docker host VM:

image

Our next step is to add a Desktop to the Docker Host VM, using vagrant ssh to connect into the VM and  sudo apt-get install –no-install-recommends lubuntu-desktop to actually add the desktop.

image

This will take considerable time. Finally:

image

and the desktop is set up.

Still inside the Docker Host VM, we connect into the Docker container with docker exec -it <container id> bash (after using docker ps -a to get hold of the container id for my-desktop-base-container)

image

Now we use Puppet to provision a GUI application (in this case simply the Java JDK/JRE) – puppet apply –debug –modulepath=/puppet/modules /puppet/manifests/base.pp.

image

When Puppet is done – Java is set up and ready to run.

image

Exit the container, commit the container and create a new image – docker commit <containerId > me/java-gui:1.0:

image

Exit from the Docker Host VM, halt the container (vagrant halt) and the Docker Host VM (vagrant halt <dockerhost vm identifier) through Vagrant

image

Start Docker Host VM through VirtualBox GUI – this will launch the GUI

image

Login – vagrant/vagrant:

SNAGHTML39a14ab

And open a terminal:

image

You can check whether Docker is available and what the situation is for containers:

image

 

Launch a Docker container for the new Docker image using special options: -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix – and run the GUI application inside Docker Container:

First: docker run -ti -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY me/java-gui:1.0 /bin/bash

Then inside the container: su – oracle, navigate to the bin folder for the Java JRE and run jcontrol. When the GUI appears – we have achieved our objective.

 

image

 

Edit: with VirtualBox 5.0 the workflow can indeed be different. This release of Oracle VirtualBox supports the ability to enter the GUI for a box that was started by Vagrant from the command line.

So adding the desktop to the Docker Host VM, exit the VM, halt the VM with Vagrant, then restart the VM with Vagrant. From VirtualBox GUI you can see the VM running and using the new right mouse option Show on the VM, we can open a remote desktop session and working inside the VM.

 

Resources

Source at in GitHub: https://github.com/lucasjellema/vagrant-docker-puppet-desktop.

Running GUI apps with Docker by Fábio Rehm

Getting to know Docker – a better way to do virtualization? by Mark Nelson

One Response

  1. John-Paul Cunliffe November 28, 2015