Running GUI apps in Docker containers using VNC

In case you don’t feel like reading yet another rant, this is the gist of it:

1) Run your container and expose port 5901 to your host
docker run -p 5901:5901 -t -i ubuntu

2) set up VNC server in the container and run it

sudo apt-get install vnc4server
vnc4server -geometry 1400x1000

3) export $DISPLAY environment variable

export DISPLAY=<change this to the right DISPLAY name from vnc server output, see screenshot below>

4) run your GUI app
5) connect to the VNC server (127.0.0.1:5901) from your host OS using one of the freely available VNC clients.
I used TightVNC and it sure was tight.

That’s it. Now if you feel like reading, I can explain my use case. Read on.

I use Docker containers as my Linux environment for whatever it is that I’m doing.
Be it SSHing into other Linux boxes or doing development, I do it all in a docker container.
And the reason for that is that for a while now I’ve been using Windows as my primary laptop OS.
Frankly, windows has come a long way and I know it sounds kind of weird, but I mostly enjoy using it.
The only trouble is that there are still not that many decent Linux laptops available on the market. But that is yet another rant-full (is there such a word?) topic.

Anyways, back to the problem at hand – running GUI apps in Docker containers.
Right, why do I need to run GUI (X) apps at all?
Well one reason is so I could use kdbg and other potentially useful tools like that.

I use Docker for Windows, which in turn uses HyperV and that pretty much excludes me using VirtualBox.
And I’m not about to start using separate HyperV VM’s just so I can run some GUI apps. Docker it is.

So the only question that remains is how to actually do it.
Now, normally, if you’d use OSX or Linux as your host OS, you can simply expose your X11 socket to the docker container and be done with it.

Since I’m on windows, I have few other options, such as running an X server and then configuring my container to use that one or using VNC. Well, technically, there’s also nomachine, but I’ll skip that as it’s not open source.

Sidetracked again, I know.

OK, so I want to use a GUI app running in a Linux container from my Windows machine.
What’s the way of least resistance here?

First, when running the container, publish the TCP port (5901 by default) that VNC server is going to use.
It could be as simple as:

docker run -p 5901:5901 -t -i ubuntu

Now, install a VNC server inside of your container, there are several options, I went with vnc4server:
sudo apt-get install vnc4server

You can start it up now by running vnc4server.
If you’re doing it for the first time (which most likely is the case as it is a fresh container after all), you’ll have to supply a password to be used to protect your VNC sessions and once it starts up it will tell you the DISPLAY name that you can now use.

For example, it looks like so, when I ran it:

fx ~ vnc4server

You will require a password to access your desktops.

Password:
Verify:

New 'dc56ff59ac7e:1 (fx)' desktop is dc56ff59ac7e:1

Creating default startup script /home/fx/.vnc/xstartup
Starting applications specified in /home/fx/.vnc/xstartup
Log file is /home/fx/.vnc/dc56ff59ac7e:1.log

Note the DISPLAY name dc56ff59ac7e:1. Now that you have it, you can either prepend it when you run your application or export it in your shell session. For example:

export DISPLAY=dc56ff59ac7e:1
kdbg &

VoilĂ . All that remains is to connect to the VNC server from your host OS.
In case of windows, there seem to be different options available when it comes to VNC viewers, any one of them should
work. The address to use for connecting will be 127.0.0.1:5901

It looks like running some sort of half-way decent window manager is a good idea, otherwise, for example the kdbgwas not being displayed nicely.
So what I’m doing is running fluxbox and then launching kdbg from the GUI mode. Works great.