slingeraap
slingeraap

Reputation: 578

FROM...AS in Dockerfile not working as I expect

I am just learning to use Docker, so please bear with me.

I want to make a docker image that builds on top of another docker image I have already built. In my dockerfile, I refer to a specific version of the base image, but for the sake of maintainability, I only want to mention that version only once in the dockerfile. The dockerfile documentation seems to suggest to me that I can use the 'AS' keyword to map a symbolic name to the specific version tag. In the --from parameter to a next COPY instruction, I should then be able to use the symbolic name instead of the specific image:version tag.

This is my dockerfile:

FROM base:2.0 AS my_base

WORKDIR /child2

COPY --from=my_base /base /child2
COPY . /child2

CMD ["python", "-u", "child2.py"]

When I build using this dockerfile with

docker build -t child2 .

I get the following error:

Step 1/5 : FROM base:2.0 AS my_base
 ---> c5e2be45da55
Step 2/5 : WORKDIR /child2
 ---> Using cache
 ---> 1b5a4ad816c9
Step 3/5 : COPY --from=my_base /base /child2
invalid from flag value my_base: pull access denied for my_base, repository does not exist or may require 'docker login'

I did use 'docker login', but I got the exact same error again.

Do I make some mistake in the syntax of the dockerfile, or is my assumption on the use of the AS keyword simply incorrect?

I am using Docker version 18.09.2 on Windows 10.

Upvotes: 23

Views: 35463

Answers (1)

atline
atline

Reputation: 31564

The FROM...AS is for multi-stage builds:

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. To show how this works, let’s adapt the Dockerfile from the previous section to use multi-stage builds.

Your dockerfile just has one stage, meanless to use it, a valid use case is next:

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

Here, the built out binary in first stage(builder) could be copied to the second stage which with a new base(FROM alpine:latest). The benefit is: it can reduce the golang tool chain setup in second stage, just use the binary from the first stage.

UPDATE 20221012 to fit new comments:

Looks official guide did not afford a sample app.go, next is a sample:

package main
func main() {
}

Upvotes: 41

Related Questions