I am seeing a dockerfile whose code is given below:
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"]
On the 2nd last line there is COPY --from=publish /app/publish .
. I don't understand why --from is used and what purpose it solves. Can you please help me to understand it?
This is a multi-stage build. This is used to keep the running docker container small while still be able to build/compile things needing a lot of dependencies.
For example a go application could be build by using:
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"]
So in the first part we need a complete go environment to compile our software. Notice the name for the first part and the alias builder
FROM golang:1.7.3 AS builder
In the second part beginning from the second FROM we only need the compiled app and no other go dependencies anymore. So we can change the base image to using a much smaller alpine Linux. But the compiled files are still in our builder image and not part of the image we want to start. So we need to copy files from the builder image via
COPY --from=builder
You can have as many stages as you want. The last one is the one defining the image which will be the template for the docker container.
You can read more about it in the official documentation: https://docs.docker.com/develop/develop-images/multistage-build/
you'll find this commonly in a multi-stage docker build.
As you can see there's four build stage there. The base
, build
, publish
, and final
build. In the final
build, on the third instruction, you can see that you're copying a file from the previous build, the publish
build.
Your third build, the publish
build, is creating something in the /app/publish
directory. So, in order to access that directory and copy the content inside it, your final
build (third instruction) is copying from that directory using --from=publish
so you can access the directory from the previous build.
Comment from https://docs.docker.com/develop/develop-images/multistage-build/
"You can use the COPY --from instruction to copy from a separate image, either using the local image name, a tag available locally or on a Docker registry, or a tag ID. The Docker client pulls the image if necessary and copies the artifact from there."
Basically, COPY --from is used for the multistage build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With