docker-compose 中的 ROS 导致“bash:第 0 行:cd:MYPROJECT:没有这样的文件或目录”

docker-compose 中的 ROS 导致“bash:第 0 行:cd:MYPROJECT:没有这样的文件或目录”

我是 docker 的新手,我尝试创建一个 docker-compose,让两个容器可以互相看到。这个问题可能与许多其他关于“没有这样的文件或目录”错误的问题重复,但其他问题到目前为止还没有帮助我解决这个问题。

它是针对 ROS 项目的,框架取自“小型 ROS 示例“,其中,主要是docker-compose-explicit.yml示例,并且该教程有效。

现在,使用我的项目图像并更改一些其他内容:

  • 桥接网络已运行,可通过简单的“hello world”回声和ping masteraso进行测试。
  • 我不确定可解析的体积。

我没有找到像容器似乎自动执行的那样进入图像工作目录的方法。好像我没有挂载 MYPROJECT,它是在创建映像时安装在 /root 中的。

这个容器的运行不需要挂载参数,它似乎自动以根目录作为镜像的工作目录启动,然后可以访问 MYPROJECT 目录而不会出现错误:

docker run -it --rm --name test MYPROJECT /bin/bash -c "cd MYPROJECT"

这个docker-compose文件不起作用。我已添加ls查看“容器当时看到的内容”:

version: '2'

services:

  master:
    build: .
    networks:
      - MYPROJECT_bridge
    command: bash -c "echo 'hello world' && cd MYPROJECT && ls"  

  talker:
    build: .
    networks:
      - MYPROJECT_bridge
    environment:
      - "ROS_HOSTNAME=talker.MYPROJECT_bridge"
      - "ROS_MASTER_URI=http://master.MYPROJECT_bridge:11311/"
    command: bash -c "echo 'hello world' && ls && echo '___' && cd MYPROJECT && ls"

  listener:
    build: .
    networks:
      - MYPROJECT_bridge
    environment:
      - "ROS_HOSTNAME=listener.MYPROJECT_bridge"
      - "ROS_MASTER_URI=http://master.MYPROJECT_bridge:11311/"
    command: bash -c "echo 'hello world' && ls && echo '___' && cd MYPROJECT && ls"

# "resolvable" is providing a DNS entry for the Docker bridge interface address, by default for docker0, just to avoid having to set ROS_IP for every container, see the tutorial

  resolvable:
    image: MYIMAGE
    volumes:
      - /:/MYPROJECT:rw
    command: bash -c "echo 'hello world';tail -f /dev/null;"

volumes:   
  MYPROJECT:

networks:   
  MYPROJECT_bridge:

侦听器的错误输出示例:

Attaching to MYPROJECTPATH_listener_1, MYPROJECTPATH_resolvable_1
resolvable_1  | 2021/02/06 10:43:42 systemd: disabled, cannot read /tmp/systemd: stat /tmp/systemd: no such file or directory
resolvable_1  | 2021/02/06 10:43:42 Starting resolvable 0.2 ...
resolvable_1  | 2021/02/06 10:43:42 got local address: 172.26.0.2
resolvable_1  | 2021/02/06 10:43:42 error adding container 98682f299611: unknown network mode%!(EXTRA string=MYPROJECTPATH_MYPROJECT_bridge)
resolvable_1  | 2021/02/06 10:43:42 error adding container 55f741dabd1c: unknown network mode%!(EXTRA string=MYPROJECTPATH_default)
listener_1    | hello world
listener_1    | bin
listener_1    | boot
listener_1    | dev
listener_1    | etc
listener_1    | home
listener_1    | lib
listener_1    | lib64
listener_1    | media
listener_1    | mnt
listener_1    | opt
listener_1    | proc
listener_1    | root
listener_1    | ros_entrypoint.sh
listener_1    | run
listener_1    | sbin
listener_1    | srv
listener_1    | sys
listener_1    | tmp
listener_1    | usr
listener_1    | var
listener_1    | ___
listener_1    | bash: line 0: cd: MYPROJECT: No such file or directory

如何修复最后一行No such file or directory?无法进入 MYPROJECT 目录。

这个问题可能还涉及,但我不确定:当使用已经在容器上运行且没有 mount 参数的相同 bash 命令时,为什么以及如何在 docker-compose 文件中挂载卷?并且在开始cannot read /tmp/systemd和时都有警告unknown network mode%,但该错误也出现在教程中并且不会阻止它工作。

更新:如果我在每个服务中加载图像(这样您image: MYIMAGE也可以在主服务、谈话者和监听器中看到),尽管命令找不到主服务,但它们在每个服务中都有效:

RLException: ERROR: unable to contact ROS master at [http://master.MYPROJECT_bridge:11311] talker_1 | The traceback for the exception was written to the log file

我怎样才能在可解析中只加载一次图像,以便其他服务使用该图像?或者更广泛地说,如果可能不需要可解析:如何使用docker-compose让ROS在Docker上运行?

答案1

回答我自己的问题。更好的方法是参加另一个 ROS 撰写教程,请参阅 2.)。

  1. 尝试运行给定的docker-compose:

我不能再肯定地说主要的变化是什么。但至少最终还是奏效了。

version: '2'

services:

  master:
    build: .
    command: roscore 

  talker:
    build: .
    workdir: /MYPROJECT
    environment:
      - "ROS_HOSTNAME=talker"
      - "ROS_MASTER_URI=http://master:11311/"
    command: bash -c "source devel/setup.bash && MYCOMMAND --wait"

  listener:
    build: .
    workdir: /MYPROJECT
    environment:
      - "ROS_HOSTNAME=listener"
      - "ROS_MASTER_URI=http://master:11311/"
    command: bash -c "source devel/setup.bash && MYCOMMAND --wait"

  resolvable:
    image: MYIMAGE
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
      - /etc/resolv.conf:/tmp/resolv.conf

如果我想cd MYPROJECT &&不使用workdir:,我可能必须将卷装入每个容器,而不仅仅是“可解析”容器。请参阅在 docker-compose 中挂载卷。如何操作?如何使用docker-compose挂载主机目录?或者官方文档

尽管遵循 2.) 的指导可能是最好的方法,但这是一种使问题的 docker-compose 工作的方法,使用没有单独网络和卷的精简脚本,因为这由“可解析”容器覆盖。您需要在talker 和 listener 的 bash 命令的命令行末尾添加--wait(前面没有);其目的与 相同,这也使容器保持活动状态,但没有。使用在测试中有效,甚至可能是主要技巧。;--wait;tail -f /dev/null;--wait

  1. 更官方的 wiki.ros.org 指南似乎更好:

根据 wiki.ros.org 官方指南的建议,ROS 和 Docker Compose 入门,这里首先只是复制粘贴:

version: '2'

networks:
  ros:
    driver: bridge

services:
  ros-master:
    image: ros:kinetic-ros-core --> replace with MYIMAGE
    command: stdbuf -o L roscore
    networks:
      - ros
    restart: always

  talker:
    image: ros:kinetic-ros-core --> replace with MYIMAGE
    depends_on:
      - ros-master
    environment:
      - "ROS_MASTER_URI=http://ros-master:11311"
      - "ROS_HOSTNAME=talker"
    command: stdbuf -o L rostopic pub /chatter std_msgs/String "hello" -r 1
    networks:
      - ros
    restart: always

  listener:
    image: ros:kinetic-ros-core --> replace with MYIMAGE
    depends_on:
      - ros-master
    environment:
      - "ROS_MASTER_URI=http://ros-master:11311"
      - "ROS_HOSTNAME=listener"
    command: stdbuf -o L rostopic echo /chatter
    networks:
      - ros
    restart: always

stdbuf -o L ...还可以使用bash -c "..."

跟问题的docker-compose有什么区别?

  • 网络的构建还有一个额外的步骤:

      networks:
        ros:
          driver: bridge
    

    这个网络在容器中被这样调用:

          networks:
            - ros
    

    虽然问题的 docker-compose 使用

      networks:
        - MYPROJECT_bridge
    

    并使用相同的方法调用网络:

      networks:
        - MYPROJECT_bridge
    
  • 我们还看到“可解析”容器根本不需要。

  • restart: always引入,以便容器不会在一个命令之后直接退出,可能与--wait1.) 中 bash 命令末尾的操作相同。问题的 docker-composetail -f /dev/null仅​​用于可解析,可能错误地希望这将适用于所有容器中图像的使用。

相关内容