Problem
I have a set of client machines that are a part of an enterprise web application. Each machine runs identical software, which is a PyQT-based web client that connects to a server. This client software is updated regularly and I would like to have some configuration/provisioning tool that allows to have the same environment on each machine and hence provide easy deployment and configuration of the software onto each of the clients' machines.
The problem is that I have tried to use Chef, but it takes a lot of effort to actually maintain Chef knowledge and skills (we do not have a dedicated Ops guy) and moreover a Chef recipe can fail if some third party repository is no longer available (this is a main stopper).
I would like to try Docker to solve the problem, but I still do not know if it is possible to set up images/containers that allow for some GUI based software to operate.
Question
Is it possible to use Docker to have a development/production environment for a GUI-based application (PyQt/QT)? If yes, what would be the first steps to approach that?
Running a GUI program in Docker can be a useful technique when you're evaluating a new piece of software. You can install the software in a clean container, instead of having to pollute your host with new packages. This approach also helps you avoid any incompatibilities with other packages in your environment.
Kitematic. Kitematic is the default GUI that ships with Docker for Mac and Windows.
If you want that UI application to display the user interface on your local machine while running the application inside the Docker Container, you will have to connect the display of the Docker Container with the display of your local machine.
Currently this question is not answered, but it is very highly ranked on Google. The other answers are mostly correct, but with some caveats that I have learned the hard way, and I would like to save others trouble.
The answer given by Nasser Alshammari is the simplest (and fastest) approach to running GTK applications inside a Docker container - simply mount the socket for the X server as a Docker volume and tell Docker to use that instead.
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage
(I would also recommend passing the -u <username-within-container>
flag, as running X11 applications as root does not always work, and is generally not recommended, especially when sharing sessions).
This will work for applications such as xterm
, as well as GTK-based applications. For example, if you try this with Firefox (which is GTK-based), it will work (note that if you are already running Firefox on the host, it will open a new window in the host rather than open a new instance of Firefox from within the container).
However, your answer asks about PyQT specifically. It turns out that Qt does not support sharing of X sessions in this way (or at least does not support it well).
If you try running a QT-based application this way, you will probably get an error like the following:
X Error: BadAccess (attempt to access private resource denied) 10 Extension: 140 (MIT-SHM) Minor opcode: 1 (X_ShmAttach) Resource id: 0x12d X Error: BadShmSeg (invalid shared segment parameter) 148 Extension: 140 (MIT-SHM) Minor opcode: 5 (X_ShmCreatePixmap) Resource id: 0xb1 X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 62 (X_CopyArea) Resource id: 0x2c0000d X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 62 (X_CopyArea) Resource id: 0x2c0000d
I say "probably" because I have not tested this approach with enough Qt applications to be sure, or dug into the Qt source code enough to figure out why this is not supported. YMMV, and you may get lucky, but if you are looking to run a Qt-based application from within a Docker container, you may have to go the "old-fashioned" approach and either
Run sshd within the container, turn on X11 forwarding, and then connect to the container using ssh -X
(more secure) or ssh -Y
(less secure, used only if you fully trust the containerized application).
Run VNC within the container, and connect to it from the host with a VNC client.
Between those two options, I would recommend the first, but see which works best for your situation.
There are many solutions to have GUI apps running in a docker container. You can use SSH, or VNC for instance. But they add some overhead and delay. The best way that I found is just to pass in the file used by the X server in the host machine as a volume to the container. Like this:
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage
Then all your GUI apps will run from container.
Hope This helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With