此Dockerfile语句有什么问题?我应该使用哪一个?

时间:2019-01-20 12:24:33

标签: docker

如果我想在Docker文件中运行例如wget,我可以输入以下内容:

RUN wget http://example.com

如果我想执行echo命令,我可以这样做

RUN echo 'Hello' >> /home/file.text

但是我也看到了这一点:

RUN bash -c 'echo $USERNAME:ros | chpasswd'

如果我想运行shell脚本,可以这样做

RUN 'bash ./install_foo.sh'

我也被推荐这样做:

RUN . /home/ros/.bashrc

我认为上面有一些无效的示例,而另一些具有微妙的语义差异。我想

  1. 了解它,以便我学习
  2. 我想运行shell脚本时应该使用什么正确的语言

1 个答案:

答案 0 :(得分:1)

这是相关的单行答案的答案:

  • 每个RUN命令都会使用新的干净环境启动一个新的shell(甚至在一个新的容器中),并且不读取任何点文件。 RUN export ...RUN . ...均为无操作,对以后的步骤没有影响。

  • 许多标准Docker路径(如docker run ... some command)根本不涉及shell,因此,如果您创建.bashrc.profile文件,则在许多情况下都将其忽略常见情况。

  • 未加引号的RUN some commandCMD some commandENTRYPOINT some command均为automatically wrapped in sh -c '...',您基本上不需要明确地说出来。 (在ENTRYPOINT中使用不带引号的形式可能是一个错误。)像CMD ["some", "command"]这样的形式并不隐式包含外壳程序(并且不扩展环境变量)。

  • GNU bash具有一些供应商扩展,但不幸的是,这些扩展得到了广泛使用。高山基础图像不包含bash。特别要注意的是,source在标准中并且做相同的事情时,不要说.

  • 如果要在映像中安装软件,最好的选择是将其安装在“系统”位置(pip install,而没有活动的虚拟环境,npm install -g,{{1 }});如果必须将其安装在其他地方,请使用Dockerfile ./configure --prefix=/usr/local指令设置所需的任何环境变量;如果您不能这样做,那么ENV包装脚本可以以编程方式设置主进程的环境(但不能设置任何ENTRYPOINT shell)。

  • 通常,docker exec将运行一个shell脚本(只要它是可执行的并且以./foo.sh行开头); #!/bin/sh也将(但不要求它是可执行的,并明确指定要使用的shell);并且bash foo.sh在当前shell的上下文中运行 (例如,只有这种形式可以更改环境变量)。