什么是dockerfile中复制命令中使用的--from

ntjbwcob  于 2022-11-22  发布在  Docker
关注(0)|答案(4)|浏览(230)

我看到了一个dockerfile,其代码如下所示:

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["FirstDockerApp/FirstDockerApp.csproj", "FirstDockerApp/"]
RUN dotnet restore "FirstDockerApp/FirstDockerApp.csproj"
COPY . .
WORKDIR "/src/FirstDockerApp"
RUN dotnet build "FirstDockerApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "FirstDockerApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FirstDockerApp.dll"]

倒数第二行是COPY --from=publish /app/publish .,我不明白为什么用--from,解决什么问题,你能帮我理解一下吗?

vi4fp9gy

vi4fp9gy1#

这是一个多阶段构建。这是用来保持运行的Docker容器较小,同时仍然能够构建/编译需要大量依赖项的内容。
例如,go应用程序可以使用以下代码构建:

FROM golang:1.7.3 AS builder
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=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

所以在第一部分中,我们需要一个完整的go环境来编译我们的软件。

FROM golang:1.7.3 AS builder

在第二部分中,从第二个FROM开始,我们只需要编译后的应用程序,不再需要其他go依赖项。因此,我们可以将基础映像更改为使用一个小得多的alpine Linux。但编译后的文件仍然在构建器映像中,而不是我们想要启动的映像的一部分。因此,我们需要通过

COPY --from=builder

你可以拥有任意多个stage。最后一个是定义图像的stage,它将成为docker容器的模板。
您可以在官方文档中了解更多信息:https://docs.docker.com/develop/develop-images/multistage-build/

sbtkgmzw

sbtkgmzw2#

在多阶段Docker构建中通常会发现这种情况。
正如你所看到的,这里有四个构建阶段。basebuildpublishfinal构建。在final构建中,在第三条指令上,你可以看到你正在从上一个构建publish构建中复制一个文件。
你的第三个构建版本,publish构建版本,正在/app/publish目录中创建一些内容。因此,为了访问该目录并复制其中的内容,你的final构建版本(第三条指令)正在使用--from=publish从该目录复制内容,以便你可以访问上一个构建版本的目录。

1sbrub3j

1sbrub3j3#

来自https://docs.docker.com/develop/develop-images/multistage-build/的注解
您可以使用COPY --from指令从单独的映像进行复制,可以使用本地映像名称、本地或Docker注册表上可用的标记,也可以使用标记ID。Docker客户端会在必要时提取映像,并从那里复制工件。
基本上,COPY --from用于多阶段构建。

flvtvl50

flvtvl504#

我只是在构建之前添加

CGO_ENABLED=0 

CGO_ENABLED=0  go build -o /go/bin/rest-api cmd/api/main.go

相关问题