云服务器Docker运行ROS,并通过VNC连接
- 使用华为云服务器
- 系统Ubuntu18
- VNC为x11vnc
安装图形界面
选择Xubuntu界面,占用资源较少,参考链接ubuntu安装gui
- 直接安装即可
sudo apt install xubuntu-core
- 安装完成后可能需要启动
startx
安装并启动x11vnc
开始用的tightvnc,后来发现不能远程启动rviz,报错信息:
[ INFO] [1537648559.395352789]: rviz version 1.12.16
[ INFO] [1537648559.395581867]: compiled against Qt version 5.5.1
[ INFO] [1537648559.395659829]: compiled against OGRE version 1.9.0 (Ghadamon)
[ INFO] [1537648559.835809950]: Stereo is NOT SUPPORTED
[ INFO] [1537648559.836059261]: OpenGl version: 3 (GLSL 1.3).
于是换成x11vnc:
参考链接:Ubuntu18.04 远程命令行下安装并启动x11vnc
- 安装
sudo apt-get install x11vnc
- 生成密码
sudo x11vnc -storepasswd
- 编辑启动文
sudo vim /lib/systemd/system/x11vnc.service
启动文件内容(USERNAME要替换成自己的用户名)
[Unit]
Description=Start x11vnc at startup.
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -env FD_XDM=1 -display :0 -auth guess -forever -loop -noxdamage -repeat -rfbauth /home/USERNAME/.vnc/passwd -rfbport 5900 -shared -o /var/log/x11vnc.log
[Install]
WantedBy=multi-user.target
- 另一个窗口启动lightdm
sudo lightdm
- 添加到服务中
sudo systemctl daemon-reload
sudo systemctl enable x11vnc.service
sudo systemctl start x11vnc.service
- 验证x11vnc服务
sudo netstat -an | grep 5900
出现:
tcp 0 0 0.0.0.0:5900 0.0.0.0:* LISTEN
tcp6 0 0 :::5900 :::* LISTEN
- 远程连接vnc
接下来就可以在远程客户端vnc连接服务器了,使用TightVNC viewer(注意将IP换成你的云服务器IP地址)
8. 远程连接vnc
目前有个问题,有时候vnc会断连,此时重启服务也不能连接到服务器桌面,于是手动启动x11vnc而不是通过服务启动。新建脚本start_x11vnc.sh,
内容如下:
nohup x11vnc -rfbport 5900 -passwd PASSWORD -create -forever -display :0 -o ~/x11vnc.log &
注意将PASSWARD为设置的密码,可以自定义,连接的时候要使用该密码。然后添加可执行权限:
chmod +x start_x11vnc.sh
运行脚本,x11vnc将在后台运行。
Docker运行ROS
- 重要但是很容易忘记的一步
xhost +
xhost命令是X服务器的访问控制工具,用来控制哪些X客户端能够在X服务器上显示。
xhost +
代表关闭访问授权,允许任何主机访问本地X服务器
- 拉取镜像
docker pull ros:melodic-desktop-full
- 创建容器并运行(注意将USERNAME换成你的用户名)
sudo docker run -it \
-e DISPLAY=unix$DISPLAY \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
-v /home/USERNAME/ros/docker_ros_ws:/home/USERNAME/ros_ws \
osrf/ros:melodic-desktop-full
- 启动master节点(注意是在容器中)
roscore
- 另外打开一个终端,进入刚才的容器,注意把
container_id
换成真实的idsudo docker exec -it container_id bash
- 在容器内设置DISPLAY变量(这一步似乎很重要,设置为0,我也不太清楚什么意思)
export DISPLAY=:0
- source一下环境变量(仍然在容器内)
source ros_entrypoint.sh
- 检查是否可以运行rviz(仍然在容器中)
rviz
若出现rviz窗口,则成功
Docker 挂载文件夹权限问题
上面的第3步:“创建容器并运行”里还有个不足之处:docker默认是以root用户运行容器的,当在容器内新建文件时,文件的所有者是root。而在容器外,我们一般是普通用户,对这些文件是没有权限的。为解决这一问题,可以利用Dockerfile新建镜像,在Dockerfile里添加用户并切换到新添加的用户。
Dockerfile如下:
FROM osrf/ros:melodic-desktop-full
RUN useradd --create-home --no-log-init --shell /bin/bash hitzhang && \
groupadd -g 129 docker && \
adduser hitzhang sudo && \
echo "hitzhang:1" | chpasswd
RUN usermod -u 1000 hitzhang && usermod -G 129 hitzhang
WORKDIR /home/hitzhang
USER hitzhang
该Dockerfile添加了名为hitzhang、用户组为docker、uid为1000、gid为129的新用户,并设置进入容器时,自动切换到hitzhang用户,同时切换工作目录到hitzhang的主目录。username、groupname不是很重要,可以随意,但是uid、gid设置成什么呢?
- id命令
- 设置
可以看到:uid=1000,gid=129。知道uid和gid就可以将Dockerfile里的id替换,构建镜像。