方法来自: https://blog.yadutaf.fr/2017/09/10/running-a-graphical-app-in-a-docker-container-on-a-remote-server/ ,感谢作者
基础:
- ssh 运行远程图形化程序(略)
- 通过挂在 socket 方式显示 docker 内的图像(略)
正文:
解决方法就是:端口转发
须知:
- ssh 显示远程图像是将 X0 的数据转发向 6000 + slot 端口。
比如:
xxx@xxx-xxx-xxx-xxxxxx:~$ echo $DISPLAY
localhost:10.0 //端口就为 6010
sudo lsof -i4:6010
sshd 32156 xxx 11u IPv4 232114 0t0 TCP localhost:6010 (LISTEN)
- 发送数据还需要验证信息,就是.Xauthority
cat .Xauthority
xxx-xxx-xxx-xxxxxx-MAGIC-COOKIE-1�_�>����!þ���� (下略)
工具: socat
# Prepare target env
CONTAINER_DISPLAY="0"
CONTAINER_HOSTNAME="root" #目标用户名,这里是 root 用户
# Create a directory for the socket
rm -r display
mkdir -p display/socket(用来存放 socket)
touch display/Xauthority (验证文件)
# Get the DISPLAY slot
DISPLAY_NUMBER=$(echo $DISPLAY | cut -d. -f1 | cut -d: -f2)
#:~$ echo $DISPLAY | cut -d. -f1 | cut -d: -f2
#10
# Create the new X Authority file
xauth -f display/Xauthority add ${CONTAINER_HOSTNAME}/unix:${CONTAINER_DISPLAY} MIT-MAGIC-COOKIE-1 ${AUTH_COOKIE}
# Proxy with the :0 DISPLAY
#这个命令接受 EOF 会断,但是忽略 EOF 也会出问题,所以借助 shell。
while true; do
socat -d -d TCP4:localhost:60${DISPLAY_NUMBER} UNIX-LISTEN:display/socket/X${CONTAINER_DISPLAY}
done
运行:
xxx@xxx-xxx-xxx-xxxxxx:~$ bash sock &
[1] 32660
xxx@xxx-xxx-xxx-xxxxxx:~$ 2019/03/18 15:07:02 socat[32675] N opening connection to AF=2 127.0.0.1:6010
2019/03/18 15:07:02 socat[32675] N successfully connected from local address AF=2 127.0.0.1:55644
2019/03/18 15:07:02 socat[32675] N listening on AF=1 "display/socket/X0"
结束:
xxx@xxx-xxx-xxx-xxxxxx:~$ killall bash
[1]+ Terminated bash sock
闲谈:
因为各种老代码环境难搞,打算直接docker,但是代码跑完总是要出几张图片看下结果的。再加上希望把主机当服务器用,带个笔记本到处跑,就有了这个需求。本来可以ssh进docker,但是内网穿透端口要钱的啊,也麻烦,穷人穷人。看到这篇文章激动的想分享出来,感谢作者。