*==========安装完docker拉取镜像时出现网络错误==========================*
在/etc/docker/路径下创建daemon.json 内容如下:

bash
{
"registry-mirrors": [
"https://do.nark.eu.org",
"https://dc.j8.work",
"https://docker.m.daocloud.io",
"https://dockerproxy.com",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.nju.edu.cn"
]
}
*==========如果服务器版本与桌面版同时安装的情况下==========================*
使用服务器版本需要将docker的上下文设置为服务器版
bash
docker context use default
使用桌面版本需要将docker的上下文设置为桌面版
bash
docker context use desktop-linux
通过指令 docker context ls
输出确认了当前活动上下文:

default后面的 * 表示它是当前激活的环境。
*==============================================================*
使用桌面docker可以把系统级docker关闭
停止系统级 Docker 服务的步骤
停止服务
bash
sudo systemctl stop docker
禁止开机自启
bash
sudo systemctl disable docker
重新启动系统级 Docker 服务的步骤
- 启用 Docker 服务
bash
sudo systemctl enable docker
这个命令会在系统的启动序列中添加 Docker 服务,使得每次系统启动时都会自动运行 Docker。
- 启动 Docker 服务
bash
sudo systemctl start docker
此命令会立即启动 Docker 服务,而不需要等待下一次系统重启。
- 检查 Docker 服务状态
bash
sudo systemctl status docker
确认 Docker 服务是否成功启动并且正在运行。
*==================================================================*
docker.service:主服务,负责运行 dockerd 守护进程。
docker.socket:一个 socket 激活机制,监听 Docker 的 Unix socket(通常是 /var/run/docker.sock)。
当你停止 docker.service,但 docker.socket 仍然启用 时,只要有任何程序尝试连接 /var/run/docker.sock,系统就会自动重新启动 docker.service!
sudo systemctl stop docker.service docker.socket
这条命令会同时停止主服务和 socket 监听器。
sudo systemctl disable docker.service docker.socket
这样系统重启后,Docker 不会自动启动。
*=================================================================*
*==========================docker常用命令===========================*
bash
docker ps #查看当前运行中的容器
docker ps -a # 查看容器状态
docker images # 查看镜像列表
docker rm container-id # 删除指定 id 的容器
docker stop/start container-id # 停止/启动指定 id 的容器
docker rmi image-id # 删除指定 id 的镜像
docker volume ls # 查看 volume 列表
docker network ls # 查看网络列表
docker cp /home/dj/champ ros_melodic_test:/root/champ # 把主目录下的/home/dj/champ文件夹复制进入/root/champ
docker start ros_melodic_test # # 启动已停止的容器
docker exec -it ros_melodic_test bash # 进入容器
docker rm ros_melodic_test # 删除容器(当不再需要时)
########################创建容器命令#################################
bash
xhost +local:docker
docker run -it \
--gpus all \
--env="NVIDIA_DRIVER_CAPABILITIES=all" \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--env="XDG_RUNTIME_DIR=/tmp/runtime-root" \
--volume=/tmp/.X11-unix:/tmp/.X11-unix \
--device=/dev/snd \
--name=ros_melodic_test \
osrf/ros:melodic-desktop-full \
bash -c "source /opt/ros/melodic/setup.bash && mkdir -p /tmp/runtime-root && chmod 700 /tmp/runtime-root && exec bash"
#############################################################################
这条 docker run 命令用于启动一个名为 melodic_test 的 Docker 容器,并且针对运行 ROS (Robot Operating System) 桌面完整版镜像进行了一些特定的配置,以支持 GPU 加速和图形界面显示。下面是每个参数的详细解释:
bash
docker run:Docker 命令,用于创建并启动一个新的容器。
-it:两个参数,-i 表示交互模式,保持 STDIN 打开,即使不附加到容器终端;-t 分配一个伪终端,为容器提供一个文本命令行界面。
--gpus all:允许容器访问宿主机上所有的 GPU 设备。这通常需要 NVIDIA Container Toolkit 的支持。
--env="NVIDIA_DRIVER_CAPABILITIES=all":设置环境变量,指示 Docker 容器需要完整的 NVIDIA 驱动能力,这通常用于启用 GPU 加速。
--env="DISPLAY=$DISPLAY":设置环境变量 DISPLAY,用于图形界面的显示。这里使用宿主机的 DISPLAY 环境变量值,使得容器内的图形界面程序可以在宿主机上显示。
--volume=/tmp/.X11-unix:/tmp/.X11-unix:挂载卷,将宿主机的 /tmp/.X11-unix 目录挂载到容器的相同路径,这个目录包含了 X11 服务器的 UNIX 域套接字,用于图形界面的通信。
--volume=/dev/dri:/dev/dri:挂载卷,将宿主机的 /dev/dri 目录挂载到容器的相同路径,这个目录包含了 Direct Rendering Infrastructure (DRI) 设备文件,用于 GPU 硬件的直接访问。
--device=/dev/snd:授予容器访问宿主机的 /dev/snd 设备的权限,这是声卡设备文件,用于音频输入输出。
--device=/dev/dri:再次授予容器访问宿主机的 /dev/dri 设备的权限。这个参数和上面的 --volume 参数一起确保容器可以访问 GPU 设备。
--name=ros_melodic_test:为容器指定一个名称,这里名称为 ros_melodic_test。
osrf/ros:melodic-desktop-full:指定要使用的 Docker 镜像,这里是 ROS (Robot Operating System) 的 melodic 桌面完整版镜像。
如果你已经有一个工程文件夹(champ文件夹),需要在容器中运行挂载,例如--volume=/home/dj/champ:/root/champ \ 把主目录中的
bash
docker run -it \
--gpus all \
--env="NVIDIA_DRIVER_CAPABILITIES=all" \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--env="XDG_RUNTIME_DIR=/tmp/runtime-root" \
--volume=/home/dj/champ_ws:/root/champ_ws \
--device=/dev/snd \
--name=champ_1 \
osrf/ros:melodic-desktop-full \
bash -c "source /opt/ros/melodic/setup.bash && mkdir -p /tmp/runtime-root && chmod 700 /tmp/runtime-root && exec bash"
#############################################################################
使用教程视频:https://www.bilibili.com/opus/830115082659692564
#############################################################################
创建可以可视化的docker容器
bash
docker run -it \
--platform linux/arm64 \
--name ubuntu_arm \
--network host \
-u $(id -u):$(id -g) \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:/root/.Xauthority \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
ubuntu:22.04-arm64 /bin/bash
创建后容器内的主机名会变成和宿主机(物理电脑)一样的名字 dj-H310M-DS2V。
这是因为你使用了 --network host 参数。在这个模式下,容器会共享宿主机的网络栈和主机名。
证明 X11 转发配置大概率成功,因为容器现在能直接"看到"宿主机的显示环境。
创建可以可视化x86架构的docker容器
bash
docker run -it \
--name ubuntu_x86 \
--network host \
-u $(id -u):$(id -g) \
-e DISPLAY=$DISPLAY \
-e QT_X11_NO_MITSHM=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:/home/$(whoami)/.Xauthority:ro \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
ubuntu:22.04-amd64 \
/bin/bash
备注:加入下面这三行容器内的主机名会变成和宿主机(物理电脑)一样的名字 就是会给宿主机(物理电脑)一样的文件系统结构
可视化的时候就不用在宿主机(物理电脑)上执行 xhost +local:root
-u (id -u):(id -g)
-v /etc/passwd:/etc/passwd:ro
-v /etc/group:/etc/group:ro
####################打包镜像并部署##########################################
打包镜像流程是:
当前容器 → commit 成镜像 → save 成 tar 包 → scp 到 RK3576 → docker load → docker run
- 在当前 x86 电脑上打包容器
先确认容器名:
bash
docker ps -a
把当前容器保存成镜像:
bash
docker commit ubuntu_rk3576 ubuntu_rk3576_ros2:humble
查看镜像:
bash
docker images
- 导出镜像为 tar 包
bash
docker save ubuntu_rk3576_ros2:humble | gzip > ubuntu_rk3576_ros2_humble.tar.gz
- 通过 SSH 传到另一块 RK3576 板子
假设板子 IP 是:
192.168.1.100
用户名是:
root
执行:
bash
scp ubuntu_rk3576_ros2_humble.tar.gz root@192.168.1.100:/root/
如果板子用户名不是 root,例如 firefly:
bash
scp ubuntu_rk3576_ros2_humble.tar.gz firefly@192.168.1.100:/home/firefly/
- SSH 登录 RK3576 板子
bash
ssh root@192.168.1.100
或:
bash
ssh firefly@192.168.1.100
- 在 RK3576 板子上导入镜像
bash
docker load < ubuntu_rk3576_ros2_humble.tar.gz
查看:
bash
docker images
应该能看到:
bash
ubuntu_rk3576_ros2 humble
- 在 RK3576 板子上运行容器
推荐这样启动:
bash
docker run -it \
--name ubuntu_rk3576_ros2 \
--network host \
ubuntu_rk3576_ros2:humble \
/bin/bash
如果需要图形界面,例如 turtlesim、rviz2:
bash
xhost +SI:localuser:root
docker run -it \
--name ubuntu_rk3576_ros2 \
--network host \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
ubuntu_rk3576_ros2:humble \
/bin/bash
如果RK板卡上没有图形界面(普遍推荐)
bash
docker run -it \
--name ubuntu_arm_ros2 \
--network host \
--privileged \
-v /dev:/dev \
ubuntu_arm_ros2:humble \
/bin/bash
- 进入容器后测试 ROS2
bash
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp talker
另一个 SSH 终端进入同一个容器:
bash
docker exec -it ubuntu_rk3576_ros2 /bin/bash
执行:
bash
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp listener
重要提醒
如果你之前在容器里(.bashrc)写了:
bash
export ROS_LOCALHOST_ONLY=1
部署到真实 RK3576 板子后,如果只在板子内部通信,可以保留。
但如果你要和外部电脑通信,比如:
RK3576 ↔ PC上的RViz
RK3576 ↔ 其他ROS2设备
RK3576 ↔ 机器人主控
就要删掉或改成:
bash
export ROS_LOCALHOST_ONLY=0
编辑:
nano ~/.bashrc
建议真实板子上保留:
bash
source /opt/ros/humble/setup.bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
#############################################################################