在码头工作者中我想这样做:
git clone XYZ
cd XYZ
make XYZ
但是因为没有cd命令,我必须每次传入完整路径(make XYZ / fullpath)。对此有什么好的解决方案吗?
答案 0 :(得分:406)
要更改为其他目录,请使用WORKDIR。 WORKDIR之后的所有RUN,CMD和ENTRYPOINT命令都将从该目录执行。
RUN git clone XYZ
WORKDIR "/XYZ"
RUN make
答案 1 :(得分:106)
您可以在RUN上运行脚本或更复杂的参数。以下是我之前下载的Dockerfile示例:
RUN cd /opt && unzip treeio.zip && mv treeio-master treeio && \
rm -f treeio.zip && cd treeio && pip install -r requirements.pip
由于使用了'&&',如果以前的所有命令都成功,它只会进入最后的'pip install'命令。
事实上,因为每次运行都会创建一个新的提交& (目前)一个AUFS层,如果你在Dockerfile中有太多的命令,你将用尽限制,所以合并RUN(当文件稳定时)可能是一个非常有用的事情。
答案 2 :(得分:28)
newValue
答案 3 :(得分:3)
我想知道两次 WORKDIR
是否有效,但它有效 :)
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y python3.6
WORKDIR /usr/src
COPY ./ ./
WORKDIR /usr/src/src
CMD ["python3", "app.py"]
答案 4 :(得分:0)
请注意,如果您必须在 bash
shell 中运行,则不仅需要 RUN make
,还需要之前调用 bash
shell,因为在 Docker 中,您默认情况下在 sh
shell 中。
取自 /bin/sh: 1: gvm: not found,表示或多或少:
<块引用>你的 shell 是 /bin/sh,但源期望 /bin/bash,也许是因为它
将其初始化放在 ~/.bashrc
中。
换句话说,这个问题可能发生在使用“sh”shell 而不是“bash”的任何设置中,导致"/bin/sh: 1: MY_COMMAND: not found"
。
在 Dockerfile 的情况下,使用推荐的
RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash'
或使用“[]
”(我宁愿不使用):
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"]
bash 的每个新 RUN 都是孤立的,“从 0 开始”。例如,请注意在 Dockerfile 中的 bash 命令之前设置 WORKDIR /MY_PROJECT
不会影响 bash 命令,因为必须再次在“.bashrc”中设置起始文件夹。即使您已设置 WORKDIR,它也需要 cd /MY_PROJECT
。
旁注:不要忘记“opt/../...”之前的第一个“/”。否则,它会抛出错误:
/bin/bash: opt/ros/melodic/setup.bash: No such file or directory
作品:
=> [stage-2 18/21] RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"] 0.5s
=> [stage-2 19/21] [...]
请参阅 SuperUser 上的 “/bin/sh: 1: MY_COMMAND: not found” 以了解有关多行的外观的更多详细信息,或者您将如何填充“.bashrc”。但这有点超出了这里的实际问题。
PS:您也可以将要执行的命令放在单个 bash 脚本中,然后在 Dockerfile 中运行该 bash 脚本(尽管我更愿意将 bash 命令也放在 Dockerfile 中,这只是我的意见):>
#!/bin/bash
set -e
source /opt/ros/melodic/setup.bash