基于Docker进行项目开发时,当需要在docker容器里运行一些qt图形界面的软件以及ros等,或者要调用摄像头,输出图像等等一些需求,这个时候需要解决这个Docker “可视化”的问题,注意这里不是网上一搜一大把的那种可视化容器和管理工具,下面对这种情况处理进行如下总结:
解决方法:
linux目前的主流图像界面服务X11又支持 客户端/服务端(Client/Server)的工作模式
只要在容器启动的时候,将 『unix:端口』或『主机名:端口』共享给docker,docker 就可以通过端口找到显示输出的地方,和linux系统共用显示
1.docker显示具体操作
1)首先,在主系统里运行
$ sudo apt-get install x11-xserver-utils
$ xhost +
这两句的作用是开放权限,允许所有用户,当然包括docker,访问X11 的显示接口
2)在启动docker容器时,添加选项如下:
-v /tmp/.X11-unix:/tmp/.X11-unix #共享本地unix端口
-e DISPLAY=unix$DISPLAY #修改环境变量DISPLAY
-e GDK_SCALE #我觉得这两个是与显示效果相关的环境变量,没有细究
-e GDK_DPI_SCALE
最终的启动命令就会长类似这样
$ docker run -d
-v /etc/localtime:/etc/localtime:ro
-v /tmp/.X11-unix:/tmp/.X11-unix
-e DISPLAY=unix$DISPLAY
-e GDK_SCALE
-e GDK_DPI_SCALE
--name xxx
xxx
这样启动后的容器,运行有图形界面的程序就可以自由显示,和在本地显示一样了。需要注意的是,每次重新开机,需要在本机操作一次
xhost +
打开权限即可。
3)docker内部像运行QT GUI界面的话,则可以在运行时加上如下指令
docker run -it --net=host --env="DISPLAY" xxxx
参数解释:
--env="DISPLAY": 将主机的显示环境变量共享到容器;
--net=host:使用主机网络驱动程序运行容器;
4) 想要調用宿主機攝像頭
首先可以查看一下宿主機上存在哪些設備,在/dev路徑下
然後在運行時,通過配置device來做一個調用
docker run -it --rm --device=/dev/video0 -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix xxx
2.ssh 链接显示
大多时候我们会选择通过ssh来链接远程服务器或者docker镜像,这时候对处理结果进行实时显示就是一个头疼的事了,比如用matplotlib画图显示,有几种不同的方法可以实现。这取决于你的环境配置和需求。以下是常见的几种方式:
》方法 1:使用X11转发
X11转发允许你将远程服务器上的GUI应用程序的输出显示到本地电脑上。
- 1. 确保本地机器支持X11:
- 对于Linux或macOS,确保已经安装了X11服务(macOS需要安装XQuartz)。
- Windows用户需要安装Xming或其他X11服务。
- 2. 启动SSH时启用X11转发:
使用以下命令连接到远程服务器,确保加上`-X`或`-Y`选项(`-Y`更加安全):
ssh -Y user@remote-server
- 3. 在远程服务器上安装必要的依赖:
确保远程服务器上安装了X11相关库,并且使用了支持GUI显示的`matplotlib`后端(例如`TkAgg`、`Qt5Agg`等)。
- 4. 绘制图表:
在你的Python代码中,正常使用`plt.show()`来显示图表,图像会通过X11转发到本地显示。
》方法 2:保存图像并通过SCP下载
如果不需要实时显示图表,可以将图像保存在远程服务器上,然后下载到本地查看。
- 1. 在代码中保存图像:
使用`matplotlib`将图像保存为文件:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.savefig('output.png')
- 2. 通过SCP下载图像:
使用`scp`将远程服务器上的图像下载到本地:
scp user@remote-server:/path/to/output.png /local/path/
- 3. 本地查看图像:
下载后可以使用本地图片查看工具或在本地打开文件。
》方法 3:使用`matplotlib`的无显示后端并下载图片
如果你不需要显示窗口,只想在后台绘制并保存图像,可以使用无显示后端,例如`Agg`。
- 1. 设置`matplotlib`后端为`Agg‘:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.savefig('output.png')
- 2. 下载图像:
同样可以使用`scp`或其他文件传输工具将生成的图像下载到本地进行查看。
》方法 4:使用Jupyter Notebook远程绘图
如果你在远程服务器上运行Jupyter Notebook,可以通过浏览器在本地查看绘制的图表。
- 1. 在远程服务器上启动Jupyter Notebook:
通过以下命令启动并允许远程访问:
jupyter notebook --no-browser --port=8888
- 2. 在本地机器上通过SSH端口转发访问Jupyter:
使用以下命令将远程端口映射到本地端口:
ssh -L 8888:localhost:8888 user@remote-server
- 3. 在浏览器中访问:
打开浏览器并访问`localhost:8888`,即可在本地显示远程服务器的绘图结果。
》方法 5:使用`matplotlib`与`plotly`等在线绘图库
你还可以将`matplotlib`图表转换为在线交互式图表,如`plotly`,然后在浏览器中查看结果。
根据你的需求,以上方法各有优劣。X11转发适合需要实时交互的场景,而保存图像适合非实时需求。Jupyter Notebook则提供了更友好的远程绘图体验。
参考链接: