我目前正在使用docker创建一个可重现的构建环境(用于构建Android ROM)。现在我想运行多个构建,每个构建都有轻微的变化。每个构建都包含几个步骤,例如
如果两个版本仅在步骤3中有所不同,那么能够重复使用前两个步骤会很棒。
我在考虑两个选择:
docker build
。为每个配置创建一个dockerfile,每个步骤都有一个RUN
命令。我想这会让我使用docker的缓存 - 如果两个版本在步骤3只有不同,docker将重用一个包含步骤1和2的图层。我只会"运行"我建立的容器,用于复制完成的ROM。是否有最好的"或规范的方式来做到这一点?以这种方式使用docker build
有什么不利之处吗?
答案 0 :(得分:2)
您可以构建名为" base image"的内容,然后将其推送到docker注册表。然后,对于该图片的两个分支,您使用FROM
关键字。但是,您可以使用基本图像来代替使用FROM ubuntu:latest
这样的基本图像:
使用基本图像:
FROM repo/base-image:tag
所以你的基地可能是:
FROM ubuntu:14.04
# Step 1
COPY /tmp /tmp
# Step 2
ADD /src /src
你建立并推动:
docker build -t repo/base-image .
docker push repo/base-image
然后,在你的另外两个Dockerfiles中......
Dockerfile1
FROM repo/base-image:tag
# Step 3 specific to this Dockerfile1
ADD /something /somewhere
# Do different things
EXPOSE 443
Dockerfile2
FROM repo/base-image:tag
# Step 3 specific to this Dockerfile2
ADD /something-else /somewhere-else
# Do different things
EXPOSE 80
这样他们共有前两层,而第三层只有不同。 docker文件中的行称为层。有点像穿越树。您拥有的线越多,您拥有的层/级别就越多。但是,基于FROM repo/img:tag
行,它会告诉您从哪里继承所有以前的图层。
答案 1 :(得分:1)
第二个选项(依赖Dockerfile
s + docker build
)绝对是可行的方法。
事实上,正如您在问题中已经提到的那样,这将使Docker能够使用缓存。
另外,我记得即使只有一个Dockerfile
涉及单个FROM ...
命令,Docker的缓存也已经处于活动状态。这就是为什么在Dockerfile
中,命令的顺序很重要(最好事先运行在每次构建时不太可能改变的命令,然后是可能的命令 - 例如自定义的编译应用程序)。
您可以按照@ JabariDash的答案中详述的步骤操作,但如果您注意到中间图像repo/some-image
仅使用一次(通过另一个FROM repo/some-image
中的命令Dockerfile
),请注意,您可以避免在单独的repo/some-image
中定义此Dockerfile
:事实上,您可以将多个FROM ...
命令放在同一个Dockerfile
中,并依赖于所谓的>= 17.05
3}} Docker {{1}}的功能。