Py学习  »  docker

docker搭建流程指南

新机器视觉 • 2 周前 • 96 次点击  

1.前言


这里主要提供了一个通用的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 # 新版的docker v2默认集成了docker compose的功能


图片



3.镜像拉取


  • ROS的docker images仓库链接:https://hub.docker.com/r/osrf/ros/tags


图片


在OSRF/ROS镜像仓库中可以找到几乎所有你想要的ROS docker镜像,并在对应的ROS镜像后面可以看到一行docker pull的指令,将其复制并粘贴到我们的设备上即可对相应的ROS镜像进行拉取。这里我使用ROS2进行镜像拉取的演示。


在终端中输入完成镜像拉取:


docker pull osrf/ros:humble-desktop-full


图片


在终端中输入完成进行查询:


docker images


图片



4.启动ROS的docker镜像


因为首先我们要在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镜像名。



5. Dockerfile


可创建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



6. docker-compose.yml


配合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      # 预留所有可用 NVIDIA GPU              capabilities: [gpu] # 声明 GPU 能力:容器内可调用 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      "


  • extends: :对服务模块的复用。 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 -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                        #启动容器,-d为不进入docker终端,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                        #启动容器,-d为不进入docker终端,ros2_sim是众多服务中的一个服务docker compose ps                                    #容器查看docker compose exec ros2_sim bash                    #进入容器docker compose down  


图片



7. 问题与解决


问题


如遇到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 info


出现下面信息为成功。


图片


现在就可以拉取镜像了。


图片



参考


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)


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/199386