You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Andrea Merello e2b789ce6a XPRA is good 4 years ago
Dockerfile working without socat 5 years ago
README.md XPRA is good 4 years ago
build_docker first commit 5 years ago
run clean ups 5 years ago

README.md

Tunnelling X (GUI) in Docker + SSH

NOTE: today I discovered that xpra makes all this basically unneeded (and it's faster and it allow for detaching/reattaching)..

Docker + X (locally)

Docker GUI applications can use the host X server by:

  • propagating to the container the host's X unix socket

  • propagating to the container the host's Xauthority file

  • setting the DISPLAY variable on the docker container accordingly

i.e. -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/home/vivado/.Xauthority

The dockerizer application will try to connect to the X server as if it run on the host; it will look at its DISPLAY variable to see wich unix socket to connect to (in /tmp/.X11-unix), and it will use the authentication cookie in its ~/.Xauthority. since we "propagate" this three things from the host to the container we are OK.

SSH + X (without docker)

If we have SSH access to a remote machine, and we wish to run a graphical application, we need to

  • enable SSH X forwarding in the ssh server config (on remote machine)

  • connect to the remote machine using -X option

In this way SSH will handle everitying for us; it will tunnel the X connection on a TCP socket, and it will set the DISPLAY variable accordingly. The remote applications will connect to a TCP port (instead of a unix socket) that SSH will forward to out X server

Putting the two things together

Trying to combine the two things above is not straightforward: you need to fixup things by hand

  • you need to fix the container DISPLAY variable to point to the host IP and proper display number

  • you need to fix the container Xauthority to correcly propagate the authentication cookie

The key here is to fix things wrt the container-host docker network IPs. The container DISPLAY variable need to be adjusted so that it refers to the host docker-network IP; the same for the authentication entry in Xauthority.

While adjusting the DISPLAY variable is trivial, to fix the authentication cookie we perform this process:

  • extract the authentication cookie (AUTH_COOKIE=$(xauth list ${DISPLAY})).

  • create a new Xauthority file using this cookie, but associated to the docket-network host ip (xauth -f Xauthority add ${HOST_DOCKER_IP}:${DISPLAY_NUMBER} MIT-MAGIC-COOKIE-1 ${AUTH_COOKIE})

  • forward our forged Xauthority file to the docker container and pass to it the proper DISPLAY variable(docker run -it --rm -e DISPLAY=${HOST_DOCKER_IP}:${DISPLAY_NUMBER} -v ${PWD}/Xauthority:/home/${CONTAINER_HOME}/.Xauthority docker-x-test /bin/bash)

That's it :)

Try it

In this repo you find a working (I hope) example.

  • Connect to your remote SSH machine using -X option
  • Clone this repo there
  • Build the example container: ./build_docker
  • Run the docker container: ./run - NOTE: you may need to fix your docker host IP address and home directory in the script
  • Run an awesome GUI app in the container: xclock

The socat method

In previous commits, and somewhere on the internet, another method is used: the socat utility is used to forward the TCP socket to a UNIX socket. This kind of worked but

  • seemed overkilling to me

  • has some issues (i.e. it worked only on the first connection, then socat exits.. Some attempts adding the fork option failed..)