Dockerfile:如何从另一个镜像的最后一层创建新镜像

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"]  

就我而言,我想将RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .示例中的最后一层作为唯一要保留的内容。我是否可以删除所有之前的层,也就是说,最后一层是否包含我需要的所有内容?那么,我该如何接管最后一层?在示例中,我需要/go/src/github.com/alexellis/href-counter/app在第一张图片中选择一个文件夹--from=0(“FROM 命名空间"),然后我将其复制到第二个图像的构建上下文中.。但是我如何知道该文件夹或需要复制什么才能在其上运行一个完全正常工作的容器?我希望能够复制一个层,而不是一个文件夹。

我尝试这个想法来获得更小且安全的第二张图像:

  • 删除在前一层使用的私钥,按照以下建议在 Docker 容器内使用 SSH 密钥+评论;
  • 而且,如果我将所有“构建数据”都保存在其中,我的图像就会太大了。

答案不需要拘泥于示例Dockerfile。

第一个答案后编辑:

我需要知道要接管到下一张图片的目录。这非常困难,因为我安装了许多 Python 包和 ROS,它们涉及很多目录,而不仅仅是 git 项目目录。我需要复制 .bashrc。我是否必须选择复制所有这些,复制所有内容是否有趣?由于我不确定“构建数据”是否完全保存在目录中,也许它只是在层中?如果复制所有内容是诀窍,我该怎么做,只需

COPY --from=0 . .

也许?

提问者的代码答案

这是我根据以下答案编写的代码:

在 Docker 容器内使用 SSH 密钥

答案1

当你说

COPY --from=something /source /target

您将该副本的上下文从构建上下文更改为另一个映像。在上述情况下,映像是something,可以是映像名称、阶段编号或 ,前一个阶段可以将其阶段名称命名为FROM base as something,然后该阶段的结果将被称为something

随着上下文的改变,您/source将从该上下文中复制特定文件,将其/target作为结果映像中的新层。不会复制任何其他内容,包括早期阶段的构建历史记录,也不会复制文件系统中的任何其他文件。

但是,如果something您需要从注册表中提取外部图像,则需要提取整个图像才能/source在该图像中找到它,而该图像可能会分布在多个层上。

这是其中之一注入凭证的几种方法。但是请注意,构建主机会将这些凭据存储为早期阶段的层,希望您不要推送这些层。注入凭据的其他选项包括根本不在构建中执行此操作(在运行构建之前拉取 git 存储库),或使用buildkit 的--mount语法

相关内容