1. ホーム
  2. docker

[解決済み] dockerfileのcopyコマンドで使われる-fromとは?

2022-03-08 04:38:19

質問

以下のような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"]

最後の2行目には COPY --from=publish /app/publish . . なぜ-fromが使われているのか、また、どのような目的をもって解決しているのか、理解できません。どうか理解する手助けをしていただけませんか?

どのように解決するのですか?

これは、多段ビルドです。これは、実行中の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環境が必要なのです。最初の部分の名前と、エイリアスである builder

FROM golang:1.7.3 AS builder

2番目のFROMから始まる2番目のパートでは、コンパイルされたアプリだけが必要で、他のgoの依存関係はもうありません。ですから、ベースイメージをより小さなalpine Linuxを使用するように変更することができます。 しかし、コンパイルされたファイルはまだビルダーイメージにあり、起動するイメージの一部ではありません。 そのため、以下の手順でファイルをビルダーイメージからコピーする必要があります。

COPY --from=builder

ステージはいくつでも用意できます。最後のステージは、Dockerコンテナのテンプレートとなるイメージを定義するものです。

詳しくは公式ドキュメントをご覧ください。 https://docs.docker.com/develop/develop-images/multistage-build/