Docker从1个Dockerfile构建2个映像

时间:2018-06-28 10:27:31

标签: docker dockerfile

我设置了最终版本的2个变体,分别是完整版和苗条版。两种变体都有2个容器,分为2个步骤:

  • 获取完整/精简版的所有要求并制作一个容器
  • 将应用安装在完整或细长的基本容器上,然后制作最终容器

因此,只有在基本容器之间切换时,第二步容器才是相同的。 Dockerfile中支持多个FROM,但是我认为它可以满足稍有不同的需求(所有Google搜索都指向此)。

所以我想知道我们最好的方法是将最后一步作为1个Dockerfile,它将生成2个映像,并且仅在2个不同的FROM之间切换。我正在考虑两种不同的方法:

  • 具有Dockerfile.template和bash从模板生成2个定制的Dockerfile。
  • 让3个不同的文件具有共同的逻辑,然后具有2个唯一的Dockerfile(用于完整/精简安装),并且在两个文件中都包含共同的逻辑。

但我想知道,还有没有更好的方法?还是我想念什么?

3 个答案:

答案 0 :(得分:2)

您也可以在ARG中使用FROM

ARG BASE_IMAGE
FROM $BASE_IMAGE
....

因此,在第二部分中将BASE_IMAGE作为构建arg进行传递,并以此方式进行。扩展坞文件中的多个FROM用于多阶段构建,因此不适用于此用例,因为多阶段docker文件仍仅产生一个最终容器

答案 1 :(得分:2)

您可以在ARG中使用构建时配置。

  

FROM指令支持任何ARG声明的变量   在第一个FROM之前出现的指令。   在FROM之前声明的ARG在构建阶段之外,因此,FROM之后的任何指令都不能使用它。要使用在第一个FROM之前声明的ARG的默认值,请使用ARG指令,该指令在构建阶段内部不带值:

Dockerfile:

ARG imagename
FROM $imagename
RUN echo $imagename

运行两个不同的基本图像:

docker build --build-arg imagename=alpine .

输出:

Step 1/3 : ARG imagename
Step 2/3 : FROM $imagename
latest: Pulling from library/alpine
ff3a5c916c92: Pull complete 
Digest: sha256:e1871801d30885a610511c867de0d6baca7ed4e6a2573d506bbec7fd3b03873f
Status: Downloaded newer image for alpine:latest
 ---> 3fd9065eaf02
Step 3/3 : RUN echo $imagename
 ---> Running in 96b45ef959c3

Removing intermediate container 96b45ef959c3
 ---> 779bfc103e9e
Successfully built 779bfc103e9e

或者:

docker build --build-arg imagename=busybox .

导致:

Step 1/3 : ARG imagename
Step 2/3 : FROM $imagename
latest: Pulling from library/busybox
07a152489297: Pull complete 
Digest: sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
Status: Downloaded newer image for busybox:latest
 ---> 8c811b4aec35
Step 3/3 : RUN echo $imagename
 ---> Running in 6027fe4f5b7b

Removing intermediate container 6027fe4f5b7b
 ---> 28640f123967
Successfully built 28640f123967

另请参见this blogpost

答案 2 :(得分:0)

其他选项是从单个文件动态生成多个文件。问题是Docker 1.7.1不支持--build-arg,并且明智的是,它正在悄然失败

因此,如果Dockerfile需要在较新的和较旧的Docker上运行,则需要遵循最新版本1.7.1,该版本可以运行centos / rhel 6(在我的情况下为6.9)。

在运行docker build之前,我不得不使用envsubst用值替换变量。您可以将envsubst的结果直接流式传输到docker中,或者先将其保存到文件中。首先将其保存到文件中将使您对输入进行故障排除。例如,一个pitfal就是使用所有变量,这些变量最终可能尝试解决的问题超出您的期望,我个人始终使用envsubst并始终带有参数列出可以解决的变量,这样它就不会尝试解决其他问题。