Forward X11 over an SSH connection to container's host?

11,413

Solution 1

It looks like you're doing all of the same stuff I'm doing EXCEPT you're sharing the .Xauthority at the time of container creation. That means if you ever ssh -X into your machine after creating the container the .Xauthority will not be valid anymore. You can't ssh -X from another terminal into the same machine and go back and use the .Xauthority, ssh -X changes the .Xauthority every time for the most recent terminal. I've only got it to work by copying the .Xauthority every time I ssh -X into my machine and try and share the screen with my container.

note: I'm sharing a device and a machine id because I was forwarding a webcam output

1.Create the container and tell xhost to allow forwarding from container id:

sudo docker run -it -d \
    --net=host \
    --env="DISPLAY" \
    --env="QT_X11_NO_MITSHM=1" \
    --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
    --device="/dev/video0:/dev/video0" \
    --volume="/path/to/your/sharedDockerFiles:/root/sharedDockerFiles" \
    --volume="/etc/machine-id:/etc/machine-id" \
    yourdockerrepo/image:tag \
    bash
export containerId=$(docker ps -l -q)
sudo xhost +local:`sudo docker inspect --format='{{ .Config.Hostname }}' $containerId`
sudo docker start $containerId

2.Copy .Xauthority from host home to sharedDockerFiles directory:

sudo cp ~/.Xauthority /path/to/your/sharedDockerFiles

3.Start and attach your container

4.Copy the .Xauthority in your shared folder to your container home

sudo cp /root/sharedDockerFiles/.Xauthority ~/

5.(necessary once): Edit container's /etc/ssh/ssh_config under Host * to include:

   ForwardX11 yes
   X11Forwarding yes

6.Restart your container and reattach and run GUI app

7.If you still have problems, make sure $DISPLAY variable in the container is the same as the host's

echo $DISPLAY #do this in the container
exit
echo $DISPLAY #do this in the host, should be the same as container's
#if they aren't equal, start container and:
export DISPLAY= #put the output of your host's $DISPLAY variable here

Solution 2

Copy .Xauthority in container at the beginning of ssh session before using GUI:

sudo docker exec -i container_name bash -c 'cat > ~/.Xauthority' < ~/.Xauthority

Then, you can pass DISPLAY if using 'docker exec'. E.g. to open new bash:

sudo docker exec -it --env="DISPLAY" container_name bash

2 more possible causes for error: (in addition to accepted answer)

  • basic: You don't have ssh server or xauth in container (for ubuntu run 'apt install openssh-server xauth')

  • sneaky one: If your container hostname is different than the one from host (e.g. set via -h badge in 'docker run') you'll get the error and you have to deal with that (e.g. set the same hostname or add cookie to xauth)

Share:
11,413

Related videos on Youtube

M-Pixel
Author by

M-Pixel

Updated on September 18, 2022

Comments

  • M-Pixel
    M-Pixel over 1 year

    I'd like to run a containerized GUI application from a remote machine.

    I don't want to solve this problem by adding an ssh host to the container because

    • I already have access to the host machine over SSH
    • It adds unnecessary overhead
    • It makes the container non-portable between remote and local use

    I can already successfully run GUI apps on the host, but not from within the container. These are the steps I've taken so far:

    Host

    • xauth + (not for long term, but useful for eliminating possible problems)
    • docker-user with uid 501000 on host == docker-user with uid 1000 in container via namespace feature
    • .Xauthority file copied to docker-user home folder

    Dockerfile

    • Based on alpine
    • Installs xauth and, for testing purposes, xterm
    • Creates docker-user with proper uid/gid

    docker-compose

    • Environment variable DISPLAY forwarded in
    • Volume /home/docker-user/:/home/docker-user/:ro to provide .Xauthority cookie
    • Volume /tmp/.X11-unix:/tmp/.X11-unix:ro to provide X11 socket access
    • Runs command su - docker-user -c "export DISPLAY=$DISPLAY && xterm"
      • su used to run as docker-user
      • DISPLAY forwarded into su context

    Unfortunately, this is not yet enough. While xterm on the host OS connects to my local X server without issue, xterm in the container says Xt error: Can't open display: localhost:10.0.

    I've confirmed that "localhost:10.0" is correct, localhost exists in the container's /etc/hosts, and the cookie and socket are making it through with the right permissions.

    What else could possibly be going wrong?

  • Nikolay Frick
    Nikolay Frick over 5 years
    This solution worked for me. Apparently it was enough to just copy .Xauthority file to docker container without need to restart it.