这里主要提供了一个通用的docker构建流程,在构建任何docker的时候都可以参考这个构建流程来搭建一个专用的docker镜像。文章飞书链接docker搭建流程指南(https://my.feishu.cn/docx/EBwodWAywoxR6OxMTJVc7xylnKe)
2.安装docker和docker-compose
wget http://fishros.com/install -O fishros && . fishrossudo apt install -y docker-compose
在OSRF/ROS镜像仓库中可以找到几乎所有你想要的ROS docker镜像,并在对应的ROS镜像后面可以看到一行docker pull的指令,将其复制并粘贴到我们的设备上即可对相应的ROS镜像进行拉取。这里我使用ROS2进行镜像拉取的演示。
在终端中输入完成镜像拉取:
docker pull osrf/ros:humble-desktop-full
在终端中输入完成进行查询:
因为首先我们要在docker下使用cuda因此我们要先安装nvidia-docker2
sudo apt install -y nvidia-docker2sudo systemctl restart docker
在完成了ROS的docker镜像拉取后我进行以下镜像打开,在终端中输入命令
docker run -it --env DISPLAY=${DISPLAY} --env NVIDIA_DRIVER_CAPABILITIES=all --env QT_X11_NO_MITSHM=1 --env USER_ID=${USER_ID:-1000} --env GROUP_ID=${GROUP_ID:-1000} --device /dev/snd:/dev/snd --device /dev/dri:/dev/dri --volume /tmp/.X11-unix:/tmp/.X11-unix --volume /home/huahua:/home/ROS2 --gpus all osrf/ros:humble-desktop-full
这里我对上面启动docker里面的参数进行解释
-it:这里是-i和-t的组合。-i表示保持标准输入打开,允许用户与容器交互;-t表示分配一个伪终端,让用户在容器内进行命令行可操作。
--env:表示设置容器内的环境变量。
--env DISPLAY=${DISPLAY}:表示将主机的X11显示服务器地址设置容器,让容器内的GUI程序能够在主机屏幕上显示,例如想要使用RVIZ则需要打开此功能。
--env NVIDIA_DRIVER_CAPABILITIES=all:表示启用显卡驱动的全部功能,如果电脑不带显卡或使用不上可以不使用。
--env QT_X11_NO_MITSHM=1:取消Q应用的X11共享内存机制,主要是防止RViz在中运行时出现图形显示异常。
--env USER_ID= USE拉我D:−1000−−envG拉哦UP我D=美国东南铁路我D:−1000−− e n v GRO U P我D= {GROUP_ID:-1000}:设置容器内用户的UID和GID,确保容器内操作主机映射目录时,文件权限与主机一致。
--device:表示将主机的硬件设备直接映射到容器,让容器能够访问主机硬件。
--device /dev/snd:/dev/snd:表示映射主机的音频设备(/dev/snd是Linux设备的统一路径),让容器内的程序能够输出或输入音频。
--volume:表示将主机的目录或文件共享到容器,实现数据持久化和文件交互。
--volume /tmp/.X11-unix:/tmp/.X11-unix:共享主机的 X11 导入目录(/tmp/.X11-unix 是 X 服务器的本地通信接口),让容器内部的 GUI 程序能够通过该架构与主机的 X 服务器通信,最终在主机屏幕上显示窗口。
--volume /home/huahua:/home/ROS2:表示将主机的/home/huahua目录映射到容器的/home/ROS2目录。
--gpus all:表示允许容器访问主机的所有NVIDIA GPU。
osrf/ros:humble-desktop-full:docker镜像名。
可创建Dockerfile来快速完成对docker镜像中的环境配置
cd dockermkdir dockertouch Dockerfile
当你按照前两步进入到基础的ros2 docker镜像后,你需要对你的项目中进行依赖配置,例如我在某个项目中需要配置的依赖:
apt updateapt install -y gazeboapt install -y ros-humble-gazebo-ros-pkgsapt install ros-humble-xacro apt install ros-humble-ros2-controlapt install ros-humble-ros2-controllersapt install ros-humble-gazebo-ros2-controlapt install ros-humble-slam-toolboxapt install ros-humble-navigation2apt install ros-humble-nav2-bringupapt install ros-humble-twist-mux
这时你可以把这个堆的依赖和你的ROS docker镜像发给ai,让他给你生成一个Dockerfile文件,就是下面ai生成的Dockerfile。
FROM osrf/ros:humble-desktop-full
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \ gazebo \ ros-humble-gazebo-ros-pkgs \ ros-humble-xacro \ ros-humble-ros2-control \ ros-humble-ros2-controllers \ ros-humble-gazebo-ros2-control \ ros-humble-slam-toolbox \ ros-humble-navigation2 \ ros-humble-nav2-bringup \ ros-humble-twist-mux \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=
WORKDIR /home/huahua
RUN echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
CMD ["/bin/bash"]
这里我对上面启动docker里面的参数进行解释
FROM osrf/ros:humble-desktop-full:使用基础ROS Docker镜像。
ENV DEBIAN_FRONTEND=noninteractive:非交互模式的环境变量设置,避免安装过程中弹出外汇配置窗口(比如让你选Y/N)。
RUN:在docker中要运行多个命令,例如apt install和pip3 install。
ENV DEBIAN_FRONTEND=:重新启动终端的交互模式。
WORKDIR /home/huahua:工作目录,docker启动后的默认路径。
CMD ["/bin/bash"]:docker启动后执行默认命令,启动bash终端。
在Dockerfile的路径下运行如下命令可完成环境的快速配置,并生成新的docker镜像
docker build -t ros2_sim .sudo docker exec -it ros2_sim bash
配合Dockerfile一起使用可快速完成对docker环境的配置和新镜像的创建,实现一键式创建镜像、启动镜像和删除镜像等操作。请确保已经安装了Docker Compose工具。
cd dockertouch docker-compose.yml
可以将ROS2仿真环境docker搭建里的启动命令丢给ai,让他帮忙创建一个docker-compose.yml文件如下:
version: '3.8'
services: ros2_sim: build: context: . dockerfile: Dockerfile image: ros2-sim:latest container_name: ros2_sim tty: true stdin_open: true environment: - DISPLAY=${DISPLAY} - NVIDIA_DRIVER_CAPABILITIES=all - QT_X11_NO_MITSHM=1 - USER_ID=${USER_ID:-1000} - GROUP_ID=${GROUP_ID:-1000} devices: - /dev/snd:/dev/snd - /dev/dri:/dev/dri volumes: - /tmp/
.X11-unix:/tmp/.X11-unix - /home:/home - /dev/shm:/dev/shm deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] network_mode: host command: /bin/bash
这里我对上面docker-compose.yml里面的参数进行解释
version::Docker Compose文件版本。
services: :服务大类。
ros2_sim::自定义的服务具体名称(可通过 docker-compose 命令操作该服务,如启动/停止)。
build: :构建镜像的配置。
context: :构建上下文目录,默认推荐为.,docker-compose.yml和dockerfile推荐放在一个文件夹下。
dockerfile: :构建镜像的Dockerfile文件名,默认为Dockerfile。
image: :构建后的镜像名称。
container_name: :构建的容器名,有多个服务的时候需要区分。
tty: :是否为容器虚拟终端分配,true为分配,false为不分配,默认推荐true。
stdin_open::是否启动标准输入,对应docker exec -it中的-it。
环境::具体的环境配置。
DISPLAY=${DISPLAY}:缴交机DISPLAY变量,用于显示rviz2等GUI。
NVIDIA_DRIVER_CAPABILITIES=all:NVIDIA驱动功能开放数量,多显卡环境选择显卡驱动,默认全部。
QT_X11_NO_MITSHM=1 :禁用 QT 的 MIT-SHM 共享内存机制:解决 ROS GUI (如 RViz)黑屏、崩溃问题。
USER_ID=${USER_ID:-1000}:容器内用户UID:默认1000(Linux普通用户默认UID),避免文件权限问题。
GROUP_ID=${GROUP_ID:-1000}:容器内用户组GID:与UID对应,确保挂载目录权限一致。
devices::设备挂载,如显卡音频等。
Volumes: :目录挂载,简易机与容器文件共享。
/tmp/.X11-unix:/tmp/.X11-unix :共享 X11 帮助,实现容器 GUI 显示,之前是一个机器为 docker。
/home:/home:挂载一个机器目录到容器,这里为选择将一个机器的home(之前)挂载到docker的home(今晚)下。
/dev/shm:/dev/shm :共享内存优化。
部署::针对GPU资源分配。
network_mode::网络模式,使用以太网机网络(主机模式)。
command: :容器启动后执行的默认命令,可以使用如下完成多个指令的执行:
command: > /bin/bash -c " export DISPLAY=:0 && cd xingdong_ws && source install/setup.bash && ros2 launch gazebo gazebo.launch.py "
version: '3.8'
services: ros2_sim: build: context: . dockerfile: Dockerfile image: ros2-sim:latest container_name: ros2_sim tty: true stdin_open: true environment: - DISPLAY=${DISPLAY} - NVIDIA_DRIVER_CAPABILITIES=all - QT_X11_NO_MITSHM=1 - USER_ID=${USER_ID:-1000} - GROUP_ID=${GROUP_ID:-1000} devices: - /dev/snd:/dev/snd - /dev/dri:/dev/dri volumes: - /tmp/.X11-unix:/tmp/.X11-unix - /home:/home - /dev/shm:/dev/shm deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] network_mode: host command: > /bin/bash -c " export DISPLAY=:0 && cd xingdong_ws && source install/setup.bash && ros2 launch gazebo gazebo.launch.py " ros2_sim: build: context: . dockerfile: Dockerfile image: ros2-sim:latest container_name: ros2_sim tty: true stdin_open: true environment: - DISPLAY=${DISPLAY} - NVIDIA_DRIVER_CAPABILITIES=all - QT_X11_NO_MITSHM=1 - USER_ID=${USER_ID:-1000} - GROUP_ID=${GROUP_ID:-1000} devices: - /dev/snd:/dev/snd - /dev/dri:/dev/dri volumes: - /tmp/.X11-unix:/tmp/.X11-unix - /home:/home - /dev/shm:/dev/shm deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]
network_mode: host command: > /bin/bash -c " export DISPLAY=:0 && cd xingdong_ws && source install/setup.bash && ros2 launch gazebo gazebo.launch.py "
使用方法,在docker-compose.yml文件的路径下运行如下命令可实现对应功能。
docker-compose up -d --build --remove-orphans docker-compose up -d ros2_sim docker-compose ps docker-compose exec ros2_sim bash docker-compose down
Docker v2默认完成集成了docker-compose因此可以使用下面的命令相应功能
docker compose up -d --build --remove-orphans docker compose up -d ros2_sim docker compose ps docker compose exec ros2_sim bash docker compose down
如遇到Error response from daemon: failed to resolve reference "docker.io/osrf/ros:humble-desktop-full": failed to do request: Head "https://registry-1.docker.io/v2/osrf/ros/manifests/humble-desktop-full": dial tcp [2a03:2880:f10c:83:face:b00c:0:25de]:443: i/o timeout的问题。
这里我参考了博客【血泪经验】Docker拉取镜像超时竟是这个原因!镜像配置加速器还不够?_docker拉取镜像网络超时-CSDN博客
(https://blog.csdn.net/2301_76849350/article/details/147227440?ops_request_misc=%257B%2522request%255Fid%2522%253A%25221040468e6d5ba5cf547b6e85d6187080%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=1040468e6d5ba5cf547b6e85d6187080&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-147227440-null-null.142%5Ev102%5Epc_search_result_base4&utm_term=docker%E6%8B%89%E5%8F%96%E9%95%9C%E5%83%8F%E8%B6%85%E6%97%B6&spm=1018.2226.3001.4187),当然如果你科学上网比较稳定其实应该是能直接获取到镜像的。使用docker info可以查看当前配置。
1.打开daemon.json
sudo gedit /etc/docker/daemon.json
2.将下面的内容填入daemon.json
{ "registry-mirrors": [ "https://docker.registry.cyou", "https://docker-cf.registry.cyou", "https://dockercf.jsdelivr.fyi", "https://docker.jsdelivr.fyi", "https://dockertest.jsdelivr.fyi", "https://mirror.aliyuncs.com", "https://dockerproxy.com", "https://mirror.baidubce.com", "https://docker.m.daocloud.io", "https://docker.nju.edu.cn", "https://docker.mirrors.sjtug.sjtu.edu.cn", "https://docker.mirrors.ustc.edu.cn", "https://mirror.iscas.ac.cn", "https://docker.rainbond.cc", "https://do.nark.eu.org", "https://dc.j8.work", "https://gst6rzl9.mirror.aliyuncs.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "http://mirrors.ustc.edu.cn/", "https://mirrors.tuna.tsinghua.edu.cn/", "http://mirrors.sohu.com/" ], "insecure-registries": [ "registry.docker-cn.com", "docker.mirrors.ustc.edu.cn" ], "debug": true, "experimental": false}
4.重启docker服务
sudo systemctl daemon-reexecsudo systemctl restart docker
5. 检测配置成功与否
现在就可以拉取镜像了。
docker容器中安装ROS1/ROS2(不用配任何环境,10分钟搞定)_ros2 docker-CSDN博客(https://blog.csdn.net/zysss_/article/details/134125740?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522fc4599c84b149d3e32b9650f66b38436%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=fc4599c84b149d3e32b9650f66b38436&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-134125740-null-null.142%5Ev102%5Epc_search_result_base4&utm_term=ros2%20docker&spm=1018.2226.3001.4187)