Skip to content

Instantly share code, notes, and snippets.

@lakshaysethi
Last active December 16, 2021 21:18
Show Gist options
  • Save lakshaysethi/9f39cea4ea681a7cbd803f0b50950be0 to your computer and use it in GitHub Desktop.
Save lakshaysethi/9f39cea4ea681a7cbd803f0b50950be0 to your computer and use it in GitHub Desktop.
Use Docker to run graphical programs

this guide is for linux GUI apps for windows apps go here: https://medium.com/axon-technologies/installing-a-windows-virtual-machine-in-a-linux-docker-container-c78e4c3f9ba1

source https://www.cloudsavvyit.com/10520/how-to-run-gui-applications-in-a-docker-container/

you may want to save your images and here is a great article for that https://medium.com/@sanketmeghani/docker-transferring-docker-images-without-registry-2ed50726495f

edited the above - a bit for easier reading

You can use Docker to run graphical programs!

You can either use an existing X Server,

  • where the host machine is already running a graphical environment
  • running an X Server in Docker is theoretically possible but rarely used.
  • You’d need to run Docker in privileged mode (--privileged) so it could access your host’s hardware.
  • [WARN] BUT Starting the server would try to claim your video devices, usually resulting in loss of video output as your host’s original X server gets its devices yanked away.
  • A better approach is to mount your host’s X Server socket into the Docker container. This allows your container to use the X Server you already have. GUI applications running in the container would then appear on your existing desktop.

Forwarding An X Socket to A Docker Container

Providing a Docker container with access to your host’s X socket is a straightforward procedure. The X socket can be found in /tmp/.X11-unix on your host. The contents of this directory should be mounted into a Docker volume assigned to the container. You’ll need to use the host networking mode for this to work.

You must also provide the container with a DISPLAY environment variable. This instructs X clients – your graphical programs – which X server to connect to. Set DISPLAY in the container to the value of $DISPLAY on your host.

You can encapsulate all this configuration in one docker-compose.yml file:

version: "3"

services: app: image: my-app:latest build: . environment: - DISPLAY=${DISPLAY} volumes: - /tmp/.X11-unix:/tmp/.X11-unix network_mode: host Next, you need to create a Dockerfile for your application. Here’s an example that runs the Firefox web browser:

FROM ubuntu:latest RUN apt-get update && apt-get install -y firefox CMD ["/usr/bin/firefox"] Now build and run the image:

docker-compose build docker-compose up

A new Firefox window should appear on your desktop! The Firefox instance will run within the container, independently of any other open Firefox windows. The container will share your host’s X socket, so the containerised Firefox still shows up on your desktop.

This approach should only be used when you trust your Docker container. Exposing the host’s display server is a security risk if you’re not completely sure what lies inside the container.

Handling X Authentication You might need to authenticate the container to access the X Server. First get an X authentication token from your host machine. Run xauth list and note down one of the listed cookies. You’ll need to copy the entire line.

Inside the Docker container, install the xauth package. Then run xauth add, passing the token you copied in the previous step.

apt install -y xauth xauth add Your container should now successfully authenticate to the X Server.

OR You can run a VNC server within the container.

If you’re unable to use X socket forwarding, you could setup a VNC server inside your container. This approach lets you view graphical apps in the container by connecting from a VNC client running on the host.

Add the VNC server software to your container:

FROM ubuntu:latest RUN apt-get update && apt-get install -y firefox x11vnc xvfb RUN echo "exec firefox" > ~/.xinitrc && chmod +x ~/.xinitrc CMD ["v11vnc", "-create", "-forever"]

When you run this container, a VNC server will be created automatically. You must bind a host port to the container’s port 5900 – this is the port the VNC server will be exposed on.

Firefox gets launched on startup as it’s added to .xinitrc. This file will be executed when the VNC server launches and initialises a new display.

To connect to the server, you’ll need a VNC client on your host. Find the IP address of your container by running docker ps, noting down the container ID and passing it to docker inspect container id . You’ll find the IP address near the bottom of the output, within the Network node.

Use the container’s IP address with your VNC client. Connect on port 5900 without authentication. You should now be able to interact with the graphical programs running within your Docker container.

extra info

the X Window System.

  • X Servers such as Xorg provide the fundamental graphical capabilities of Unix systems.
  • GUI applications can’t render without an X Server available.
  • (Alternative windowing systems, such as Wayland, are available – we’re focusing on X in this article.)

Why Run GUI Apps in Docker?

  • 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. If you need to temporarily run two versions of a program, you can use Docker to avoid having to remove and reinstall the software on your host.

Conclusion

You have the choice of two approaches when running graphical programs within a containerised environment. For general use, sharing the host’s X socket usually provides the simplest solution. You may also choose to run a VNC server within the container. This approach can be safer when you didn’t create the container image.

Containerised graphical apps are useful when you’re evaluating software or need to run two versions of a package. You can use programs on your existing desktop without needing to touch your host’s configuration.

bonus commands

Saving docker image Save the docker image using docker save command. docker save --output saved-image.tar my-image:1.0.0 Alternatively, we can also use redirection to a file. docker save my-image:1.0.0 > saved-image.tar Both above command would create saved-image.tar with image data in current directory. Transferring image Once saved, transfer the .tar file to target server using any of the file transfer protocols like FTP or SCP. Loading docker image Once the .tar file is transferred to target machine, login to target machine and load the image into local registry using docker load command. docker load --input saved-image.tar Alternatively, we can also use redirection from a file. docker load < saved-image.tar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment