在 Dockerfile 中使用 RUN 命令无法执行 *catkin* 命令

4

我想在 Docker 上使用定制的 ros-indigo。我准备了以下 Dockerfile:

FROM ros:indigo-robot

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
RUN catkin_init_workspace
WORKDIR /home/catkin_ws
RUN catkin_make
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc

然而,在RUN catkin_init_workspaceRUN catkin_make处,它向我抛出一个错误,提示为:
/bin/sh: catkin_make: command not found
The command '/bin/sh -c catkin_init_workspace' returned a non-zero code: 127

令人惊讶的是,如果我将RUN更改为CMD以在catkin命令中运行,则可以成功构建,也就是说,以下Dockerfile可以正常构建

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
CMD catkin_init_workspace
WORKDIR /home/catkin_ws
CMD catkin_make
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc

更令人惊讶的是,这些catkin命令在任何ros-indigo镜像之上构建的容器中都可以完美运行。
这明确表明,使用RUN来调用catkin命令可能不是合适的方式,或者我正在错误地调用它。
现在,考虑到CMD命令的性质与RUN命令不同,在我的情况下使用它没有意义。因此,如果有人能指出正确的做法,我将不胜感激。
2个回答

3

您的第二个案例能够成功构建,是因为CMD在构建期间未被执行。 它只是定义了容器启动时要执行的默认命令。有关更多信息,请参见dockerCMD文档

问题的根源在于RUN指令使用的shell未调用~/.bashrc。 因此,环境变量不存在,无法使catkin_make或其他ros命令正常工作。 我通过运行类似下面的命令来解决这个问题。

RUN . /opt/ros/kinetic/setup.sh && \
    catkin_make

每个需要使用这些环境变量的 RUN 命令中,您都需要激活环境,因为 shell 在 RUN 命令之间不会被重用。

已编辑以包含 David Maze 的改进建议。


1
如果您使用标准的 . 命令而不是 bash 的 source 扩展命令,则它将在所有 Bourne 兼容的 shell 中工作,包括 Busybox 和 Alpine 基础镜像中的最小 shell,并且您无需设置 SHELL - David Maze
感谢您的建议,我已经相应地更新了答案。 - Joseph Moster
太棒了,它就像魔法一样奏效。非常感谢。对于未来的读者,这就是工作的Dockerfile的确切样子: FROM ros:indigo-robot RUN apt-get update && apt-get install -y build-essential RUN mkdir -p /home/catkin_ws/src RUN . /opt/ros/indigo/setup.sh && catkin_init_workspace /home/catkin_ws/src RUN . /opt/ros/indigo/setup.sh && cd /home/catkin_ws && catkin_make RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc - Sanjay

3

要让命令起作用,您需要为bash环境设置正确的配置(默认情况下,Docker使用sh来执行命令)。以下命令对我有效:

最初的回答:

FROM ros:indigo-robot

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
#RUN /opt/ros/indigo/bin/catkin_init_workspace
RUN /bin/bash -c '. /opt/ros/indigo/setup.bash; catkin_init_workspace /home/catkin_ws/src'

WORKDIR /home/catkin_ws
RUN /bin/bash -c '. /opt/ros/indigo/setup.bash; cd /home/catkin_ws; catkin_make'
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接