`bash: webots: command not found` 在我的 docker 容器中,因为有多个 FROM
`bash: webots: command not found` in my docker container because of multiple FROMs
我有一个 docker 容器,其中安装了 Webots 和 ROS2。但是,运行宁 webots
而在容器内 returns bash: webots: command not found
。为什么?
运行 webots
的容器(但没有 ROS2)
这是来自 Webots installation instructions 的容器 运行 DOES 成功 运行 webots
(但缺少我需要的 ROS2 ):
$ xhost +local:root > /dev/null 2>&1 #so webots won't say unable to load Qt platform plugin "xcb"
$ docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw cyberbotics/webots:R2021a-ubuntu20.04
容器不 运行 webots
这是我的 docker 容器,它 NOT 成功 运行 webots
,而是 bash: webots: command not found
。但是,它确实成功 运行 webots_ros2
demos(我认为这个问题与我如何从两个容器继承有关,因为如果我交换我的两个 ARG
和 FROM
语句,找到了 webots
但没有找到 ros2
。不过我不确定解决方案):
Docker 文件
# inherit both the ROS2 and Webots containers
ARG BASE_IMAGE_WEBOTS=cyberbotics/webots:R2021a-ubuntu20.04
ARG IMAGE_ROS2=niurover/ros2_foxy:latest
FROM $BASE_IMAGE_WEBOTS AS base
FROM $IMAGE_ROS2 AS image_ros2
# resolve a missing dependency for webots demo
RUN apt-get update && apt-get install -y \
libxtst6 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Finally open a bash command to let the user interact
CMD ["/bin/bash"]
launch.sh(用于启动 docker 容器)
#! /bin/bash
CONTAINER_USER=$USER
CONTAINER_NAME=webots_ros2_foxy
USER_ID=$UID
IMAGE=niurover/webots_ros2_foxy:latest
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*//ip') ];
then
xhost +local:$CONTAINER_USER
xhost +local:root
fi
sudo docker run -it --rm \
--name $CONTAINER_NAME \
--user=$USER_ID\
--env="DISPLAY" \
--env="CONTAINER_NAME=$CONTAINER_NAME" \
--workdir="/home/$CONTAINER_USER" \
--volume="/home/$CONTAINER_USER:/home/$CONTAINER_USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
--volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
$IMAGE bash\
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*//ip') ];
then
xhost -local:$CONTAINER_USER
xhost -local:root
fi
总结
如您所见,两个容器都使用 cyberbotics/webots:R2021a-ubuntu20.04
,第二个容器使用第一个容器的所有选项,但有一些额外的选项。为什么第一个容器运行webots
成功,而第二个容器找不到命令?
当您有多个 FROM
命令时,您并不是将它们的两个内容“继承”到同一个图像中——您是在执行 multi-stage build。这允许您从指定 --from
选项的那个阶段 COPY
。默认情况下,Dockerfile 中的最后一个阶段将是目标(因此,在您的示例中,您实际上只是在使用 ros2 图像。webots 图像实际上并未在那里使用。
这里有两个选择:
- 使用
COPY --from=base
从 webots 图像中仅复制您需要的文件
这可能会很困难和挑剔。您需要复制所有依赖项;如果它们是通过您的包管理器 (apt-get) 获取的,您将使 dpkg 的本地数据库不一致。
- 复制其中一个
Dockerfile
并更改它们的 FROM
只要它们都使用相同的基础分布,这可能会很好地工作。您可以进入项目的一个存储库并获取它们的 Dockerfile
,从另一个图像重建它 - 例如,只需将 cyberbotics/webots:R2021a-ubuntu20.04
的 Dockerfile 更改为 FROM niurover/ros2_foxy:latest
。不过,它可能需要修改那里的其他命令。
我最终采纳了 Leonardo Dagnino 的建议,并且奏效了。我不得不复制几个连续的 ROS2 容器的内容以使树层次结构从 webots 基本图像中工作,但它让我到达了我要去的地方。为了繁荣,这里是完整的新 Dockerfile:
# Use Webots docker container as base
ARG BASE_IMAGE_WEBOTS=cyberbotics/webots:R2021a-ubuntu20.04
FROM $BASE_IMAGE_WEBOTS AS base
# ==================================================================================
# niurover/ros2_foxy uses osrf/ros:foxy-desktop as its base, so I need to add code from
# container heirarchy all the way back to where it can stem off of `base` from above
# ==================================================================================
# ----------------------------------------------------------------------------------
# taken from Dockerfile for ros:foxy-ros-core-focal found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/ros-core/Dockerfile
# ----------------------------------------------------------------------------------
## setup timezone # NOTE commented out since timezone should already be set up
#RUN echo 'Etc/UTC' > /etc/timezone && \
# ln -s /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
# apt-get update && \
# apt-get install -q -y --no-install-recommends tzdata && \
# rm -rf /var/lib/apt/lists/*
# install packages
RUN apt-get update && apt-get install -q -y --no-install-recommends \
dirmngr \
gnupg2 \
&& rm -rf /var/lib/apt/lists/*
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# setup sources.list
RUN echo "deb http://packages.ros.org/ros2/ubuntu focal main" > /etc/apt/sources.list.d/ros2-latest.list
# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV ROS_DISTRO foxy
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-ros-core=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
## setup entrypoint # NOTE ignore this part of their Dockerfile
#COPY ./ros_entrypoint.sh /
#
#ENTRYPOINT ["/ros_entrypoint.sh"]
#CMD ["bash"]
# ----------------------------------------------------------------------------------
# taken from Dockerfile for ros:foxy-ros-base-focal found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/ros-base/Dockerfile
# ----------------------------------------------------------------------------------
# install bootstrap tools
RUN apt-get update && apt-get install --no-install-recommends -y \
build-essential \
git \
python3-colcon-common-extensions \
python3-colcon-mixin \
python3-rosdep \
python3-vcstool \
&& rm -rf /var/lib/apt/lists/*
# bootstrap rosdep
RUN rosdep init && \
rosdep update --rosdistro $ROS_DISTRO
# setup colcon mixin and metadata
RUN colcon mixin add default \
https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml && \
colcon mixin update && \
colcon metadata add default \
https://raw.githubusercontent.com/colcon/colcon-metadata-repository/master/index.yaml && \
colcon metadata update
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-ros-base=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
# ----------------------------------------------------------------------------------
# taken from Dockerfile for osrf/ros:foxy-desktop-focal (or is it osrf/ros:foxy-desktop?) found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/desktop/Dockerfile
# ----------------------------------------------------------------------------------
# This is an auto generated Dockerfile for ros:desktop
# generated from docker_images_ros2/create_ros_image.Dockerfile.em
#FROM ros:foxy-ros-base-focal # NOTE commented out since satisfied by above
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-desktop=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
# ----------------------------------------------------------------------------------
# taken from Dockerfile for niurover/ros2_foxy found at:
# https://github.com/NIURoverTeam/Dockerfiles/blob/master/ros2_foxy/Dockerfile
# ----------------------------------------------------------------------------------
#ARG BASE_IMAGE=osrf/ros:foxy-desktop # NOTE commented out since satisfied by above
# Install work packages
#FROM $BASE_IMAGE as base # NOTE commented out since satisfied by above
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
tmux \
curl \
wget \
vim \
sudo \
unzip \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install ROS Packages
RUN apt-get update && apt-get install -y \
ros-foxy-turtlesim \
~nros-foxy-rqt* \
ros-foxy-teleop-tools \
ros-foxy-joy-linux \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip3 install pyserial
#CMD ["bash"] # NOTE ignore this part of the Dockerfile
# ----------------------------------------------------------------------------------
# new stuff added on top of niurover/ros2_foxy to assist with Webots + ROS2
# ----------------------------------------------------------------------------------
# resolve a missing dependency for webots demo
RUN apt-get update && apt-get install -y \
libxtst6 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Finally open a bash command to let the user interact
CMD ["/bin/bash"]
我有一个 docker 容器,其中安装了 Webots 和 ROS2。但是,运行宁 webots
而在容器内 returns bash: webots: command not found
。为什么?
运行 webots
的容器(但没有 ROS2)
这是来自 Webots installation instructions 的容器 运行 DOES 成功 运行 webots
(但缺少我需要的 ROS2 ):
$ xhost +local:root > /dev/null 2>&1 #so webots won't say unable to load Qt platform plugin "xcb"
$ docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw cyberbotics/webots:R2021a-ubuntu20.04
容器不 运行 webots
这是我的 docker 容器,它 NOT 成功 运行 webots
,而是 bash: webots: command not found
。但是,它确实成功 运行 webots_ros2
demos(我认为这个问题与我如何从两个容器继承有关,因为如果我交换我的两个 ARG
和 FROM
语句,找到了 webots
但没有找到 ros2
。不过我不确定解决方案):
Docker 文件
# inherit both the ROS2 and Webots containers
ARG BASE_IMAGE_WEBOTS=cyberbotics/webots:R2021a-ubuntu20.04
ARG IMAGE_ROS2=niurover/ros2_foxy:latest
FROM $BASE_IMAGE_WEBOTS AS base
FROM $IMAGE_ROS2 AS image_ros2
# resolve a missing dependency for webots demo
RUN apt-get update && apt-get install -y \
libxtst6 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Finally open a bash command to let the user interact
CMD ["/bin/bash"]
launch.sh(用于启动 docker 容器)
#! /bin/bash
CONTAINER_USER=$USER
CONTAINER_NAME=webots_ros2_foxy
USER_ID=$UID
IMAGE=niurover/webots_ros2_foxy:latest
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*//ip') ];
then
xhost +local:$CONTAINER_USER
xhost +local:root
fi
sudo docker run -it --rm \
--name $CONTAINER_NAME \
--user=$USER_ID\
--env="DISPLAY" \
--env="CONTAINER_NAME=$CONTAINER_NAME" \
--workdir="/home/$CONTAINER_USER" \
--volume="/home/$CONTAINER_USER:/home/$CONTAINER_USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
--volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
$IMAGE bash\
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*//ip') ];
then
xhost -local:$CONTAINER_USER
xhost -local:root
fi
总结
如您所见,两个容器都使用 cyberbotics/webots:R2021a-ubuntu20.04
,第二个容器使用第一个容器的所有选项,但有一些额外的选项。为什么第一个容器运行webots
成功,而第二个容器找不到命令?
当您有多个 FROM
命令时,您并不是将它们的两个内容“继承”到同一个图像中——您是在执行 multi-stage build。这允许您从指定 --from
选项的那个阶段 COPY
。默认情况下,Dockerfile 中的最后一个阶段将是目标(因此,在您的示例中,您实际上只是在使用 ros2 图像。webots 图像实际上并未在那里使用。
这里有两个选择:
- 使用
COPY --from=base
从 webots 图像中仅复制您需要的文件
这可能会很困难和挑剔。您需要复制所有依赖项;如果它们是通过您的包管理器 (apt-get) 获取的,您将使 dpkg 的本地数据库不一致。
- 复制其中一个
Dockerfile
并更改它们的FROM
只要它们都使用相同的基础分布,这可能会很好地工作。您可以进入项目的一个存储库并获取它们的 Dockerfile
,从另一个图像重建它 - 例如,只需将 cyberbotics/webots:R2021a-ubuntu20.04
的 Dockerfile 更改为 FROM niurover/ros2_foxy:latest
。不过,它可能需要修改那里的其他命令。
我最终采纳了 Leonardo Dagnino 的建议,并且奏效了。我不得不复制几个连续的 ROS2 容器的内容以使树层次结构从 webots 基本图像中工作,但它让我到达了我要去的地方。为了繁荣,这里是完整的新 Dockerfile:
# Use Webots docker container as base
ARG BASE_IMAGE_WEBOTS=cyberbotics/webots:R2021a-ubuntu20.04
FROM $BASE_IMAGE_WEBOTS AS base
# ==================================================================================
# niurover/ros2_foxy uses osrf/ros:foxy-desktop as its base, so I need to add code from
# container heirarchy all the way back to where it can stem off of `base` from above
# ==================================================================================
# ----------------------------------------------------------------------------------
# taken from Dockerfile for ros:foxy-ros-core-focal found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/ros-core/Dockerfile
# ----------------------------------------------------------------------------------
## setup timezone # NOTE commented out since timezone should already be set up
#RUN echo 'Etc/UTC' > /etc/timezone && \
# ln -s /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
# apt-get update && \
# apt-get install -q -y --no-install-recommends tzdata && \
# rm -rf /var/lib/apt/lists/*
# install packages
RUN apt-get update && apt-get install -q -y --no-install-recommends \
dirmngr \
gnupg2 \
&& rm -rf /var/lib/apt/lists/*
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# setup sources.list
RUN echo "deb http://packages.ros.org/ros2/ubuntu focal main" > /etc/apt/sources.list.d/ros2-latest.list
# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV ROS_DISTRO foxy
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-ros-core=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
## setup entrypoint # NOTE ignore this part of their Dockerfile
#COPY ./ros_entrypoint.sh /
#
#ENTRYPOINT ["/ros_entrypoint.sh"]
#CMD ["bash"]
# ----------------------------------------------------------------------------------
# taken from Dockerfile for ros:foxy-ros-base-focal found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/ros-base/Dockerfile
# ----------------------------------------------------------------------------------
# install bootstrap tools
RUN apt-get update && apt-get install --no-install-recommends -y \
build-essential \
git \
python3-colcon-common-extensions \
python3-colcon-mixin \
python3-rosdep \
python3-vcstool \
&& rm -rf /var/lib/apt/lists/*
# bootstrap rosdep
RUN rosdep init && \
rosdep update --rosdistro $ROS_DISTRO
# setup colcon mixin and metadata
RUN colcon mixin add default \
https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml && \
colcon mixin update && \
colcon metadata add default \
https://raw.githubusercontent.com/colcon/colcon-metadata-repository/master/index.yaml && \
colcon metadata update
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-ros-base=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
# ----------------------------------------------------------------------------------
# taken from Dockerfile for osrf/ros:foxy-desktop-focal (or is it osrf/ros:foxy-desktop?) found at:
# https://github.com/osrf/docker_images/blob/master/ros/foxy/ubuntu/focal/desktop/Dockerfile
# ----------------------------------------------------------------------------------
# This is an auto generated Dockerfile for ros:desktop
# generated from docker_images_ros2/create_ros_image.Dockerfile.em
#FROM ros:foxy-ros-base-focal # NOTE commented out since satisfied by above
# install ros2 packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-foxy-desktop=0.9.2-1* \
&& rm -rf /var/lib/apt/lists/*
# ----------------------------------------------------------------------------------
# taken from Dockerfile for niurover/ros2_foxy found at:
# https://github.com/NIURoverTeam/Dockerfiles/blob/master/ros2_foxy/Dockerfile
# ----------------------------------------------------------------------------------
#ARG BASE_IMAGE=osrf/ros:foxy-desktop # NOTE commented out since satisfied by above
# Install work packages
#FROM $BASE_IMAGE as base # NOTE commented out since satisfied by above
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
tmux \
curl \
wget \
vim \
sudo \
unzip \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install ROS Packages
RUN apt-get update && apt-get install -y \
ros-foxy-turtlesim \
~nros-foxy-rqt* \
ros-foxy-teleop-tools \
ros-foxy-joy-linux \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip3 install pyserial
#CMD ["bash"] # NOTE ignore this part of the Dockerfile
# ----------------------------------------------------------------------------------
# new stuff added on top of niurover/ros2_foxy to assist with Webots + ROS2
# ----------------------------------------------------------------------------------
# resolve a missing dependency for webots demo
RUN apt-get update && apt-get install -y \
libxtst6 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Finally open a bash command to let the user interact
CMD ["/bin/bash"]