我正在努力将我当前的dockerfiles转换为多阶段构建以减少一些错误。我从一个基本映像开始,通过yum安装一堆东西以及我从源代码安装的一堆其他软件包。
此时,我想从一个新的图像开始,只引入通过yum安装的软件包和来自我的安装源的二进制文件。我看到有三种方法可以做到这一点,但我不喜欢第一种选择,也不知道如何做其他两种方法。
为yum install构建一个单独的Dockerfile,然后在从源安装之前将其用作我的基本映像。
我不喜欢这个选项,因为它为我的构建工作流程增加了更多。将所有内容都包含在一个Dockerfile中会很不错。也许这就是我需要的方式。
通过yum在不同的目录中安装软件包,然后复制到构建的下一个阶段。
我发现我可以通过yum install --installroot=/foo --releasever=/ packagename
在非默认目录中安装软件包,但是,这会将所有需求安装到/ foo,而不是继续使用/ usr中安装的软件包,从而导致图像显着增长。
有没有办法通过yum在不同的目录中安装软件包,但让它继续从默认目录中解析其依赖项?
通过yum安装软件包,然后从安装yum软件包之后的点开始下一个构建阶段。
有没有办法将构建阶段产生的图层用作下一个构建阶段的开始?像这样:
FROM centos7 as first
RUN some stuff
FROM first as second
RUN some stuff
FROM second
COPY --from=second ...
答案 0 :(得分:2)
使用多阶段构建
对于多阶段构建,您可以在Dockerfile中使用多个 FROM 语句。每个 FROM 指令可以使用不同的基础,并且每个指令都开始构建的新阶段。您可以有选择地将工件从一个阶段复制到另一个阶段,从而在最终图像中留下不需要的所有内容。为了说明它是如何工作的,请考虑以下示例:
Dockerfile
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
您只需要单个Dockerfile。您也不需要单独的构建脚本。只需运行docker build。
$ docker build -t alexellis2/href-counter:latest .
最终结果是微小的生产图像,大大降低了复杂性。您不需要创建任何中间图像,也不需要将任何工件提取到本地系统中。
它如何工作?
第二条 FROM 指令以 alpine:latest 映像为基础开始新的构建阶段。 COPY --from = 0 行仅将先前阶段的构建工件复制到新阶段。 Go SDK和所有中间工件都被保留了下来,没有保存在最终图像中。
答案 1 :(得分:0)
我不确定这是否可以通过Docker来实现,但这似乎是http://drone.io/的一个很好的用例 您可以在构建的不同阶段使用不同的映像,然后仅在最终的Docker映像上使用所需的文件。
答案 2 :(得分:0)
对于选项1,您有正确的想法,但对于多阶段构建,可以通过使用3阶段构建而不是单独的基本映像docker文件来实现。
使用named stages,copying from a previous stage和starting a stage from a previous stage的组合,结果如下所示。
FROM centos:latest AS yum-base
RUN yum install -y LIST_OF_YUM_DEPENDENCIES
...
FROM yum-base AS compiled_packages
RUN build_some_binaries_here
...
FROM yum-base
COPY --from=compiled_packages /usr/local/bin/file_name /usr/local/bin/file_name