Forward X11 over an SSH connection to container's host?
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)
Related videos on Youtube
M-Pixel
Updated on September 18, 2022Comments
-
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 todocker-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 asdocker-user
DISPLAY
forwarded intosu
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 over 5 yearsThis solution worked for me. Apparently it was enough to just copy .Xauthority file to docker container without need to restart it.