Docker本身的工作模式是命令行的,因为主要的使用场景可能是做服务器后端方面的比较多。但有时候我们会有在docker容器里运行一些图形界面的软件,比如使用ROS时候需要gazebo和rviz的可视化这时候就需要使用图形界面进行结果的显示。下面就做一些自己找到的一些解决方案。
原理
原理上可以把docker镜像看做一台没配显示器的电脑,程序可以运行,但是没地方显示。 而linux目前的主流图像界面服务X11又支持 客户端/服务端(Client/Server)的工作模式 。只要在容器启动的时候,将 『unix:端口』或『主机名:端口』共享给docker,docker 就可以通过端口找到显示输出的地方,和linux系统共用显示。这是大部分场景都可以使用的,但是目前的WSL2使用的是WSLg来进行图形界面的显示(使用过WSL2的应该知道,现在的WSL2可以直接在宿主机windows下直接显示界面)。WSLg主要是基于的win下的RDP远程服务器来进行图像的显示。那么我就主要介绍两种常见的场景:第一种是在虚拟机ubunt中Docker的gui应用的显示,第二种是WSL2中Docker的显示。
虚拟机中Docker应用的显示
我使用的虚拟机是ubuntu-20.04,在其中安装Docker。虚拟机和Docker的安装可以参考其它博文,安装完成之后,为了实验,直接使用Docker拉取最新的ubuntu镜像(ubuntu中安装ubuntu,套娃)。使用如下命令:
sudo docker pull ubuntu
这条命令会直接拉取最新的ubuntu镜像。然后是运行这个镜像(命令中的参数是最重要的):
sudo docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY ubuntu:latest
其中主要注意命令后跟的-v和-e参数,下面进行介绍这两个参数的作用:
- -v 是用来指定容器卷的映射,将容器映射到宿主机中,共享这个文件,这里类似于共享一下显示器
- -e 是用来指定容器的环境变量,修改环境变量DISPLAY为宿主机的环境变量
运行上述命令之后,在宿主机中新开一个终端运行下面的命令:
xhost +
运行之后会输出access control disabled, clients can connect from any host。大致意思是允许所有的连接。最后为了验证可以正确的运行可以安装一个小的图形化应用如下:
sudo apt install x11-apps -y
运行完成之后,使用xclock命令可以显示一个钟表的图形。
WSL2中Docker中应用的显示
在早期的WSL版本可以使用上面的方法进行显示,但是目前的WSL2使用的是WSLg来进行图形的显示,也就是宿主机不需要安装X-11服务器就可以完成gui功能的显示,与上面命令不同的主要是运行容器命令的容器卷映射的不同。直接显示如下图:
也就是我运行命令之后,可以直接在win10系统界面中显示。
这里使用的WSL2是ubuntu-22.04,安装docker-desktop之后,还是直接拉取最新的ubuntu镜像。使用如下命令:
sudo docker pull ubuntu
运行命令有所不同:
sudo docker run -it -v /mnt/wslg/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY ubuntu:latest
参考网上的代码还可以使用如下形式的命令来进行wsl2中gui界面的显示(也更为推荐如下形式的代码)
sudo docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /mnt/wslg:/mnt/wslg -e DISPLAY=unix$DISPLAY ubuntu:latest
主要是容器卷的映射不同,使用的是/mnt/wslg文件下来进行映射的。其它和上述步骤一样。通过这样的步骤即可在win10下使用不同的Docker镜像,enjoy youself!