I want to use variables across multi-stage docker builds. Similar to this question (unanswered at the time of writing.)
My specific use case is to build my Go project in a builder
stage and save the directory. This is done in a variable and use the same variable in the next stage(s): The BUILD_DIR
variable.
My Dockerfile is (The example in the commented lines doesn't work.):
FROM golang:1.11.5 as builder
WORKDIR /project-name
# What I want to do:
#ENV BUILD_DIR /project-name
#WORKDIR ${BUILD_DIR}
# Vendored dependencies of my project:
COPY ./vendor ./vendor
COPY ./*.go ./
# Source code:
COPY ./go.* ./
RUN GOFLAGS=-mod=vendor GOOS=linux go build .
FROM something-else:some-version
WORKDIR some-folder
# Executable from previous stage:
COPY --from=builder /project-name/executable-name .
# Config files:
COPY ./conf ./conf
# What I want to do to copy the executable:
#COPY --from=builder /${BUILD_DIR}/executable-name .
ENTRYPOINT ["./executable-name"]
To send variable we can use "ARG" solution, the "base" solution, and "file" solution.
ARG version_default=v1
FROM alpine:latest as base1
ARG version_default
ENV version=$version_default
RUN echo ${version}
RUN echo ${version_default}
FROM alpine:latest as base2
ARG version_default
RUN echo ${version_default}
another way is to use base container for multiple stages:
FROM alpine:latest as base
ARG version_default
ENV version=$version_default
FROM base
RUN echo ${version}
FROM base
RUN echo ${version}
You can find more details here: https://github.com/moby/moby/issues/37345
Also you could save the hash into a file in the first stage, and copy the file in the second stage and then read it and use it there.
From what I understand you want to copy the built program into the new docker for multistage build that the output size is smaller. Basically you do not need to send a variable you need to know were you built it in the first image and copy it from there
FROM golang:alpine as gobuilder
RUN apk update && apk add git
COPY sources/src/ $GOPATH/src/folder/
WORKDIR $GOPATH/src/folder/
#get dependencies
RUN go get -d -v
#build the binary
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/myGoProgram myGoSource.go
FROM alpine:latest
COPY --from=gobuilder /go/bin/myGoProgram /usr/local/bin/myGoProgram
ENTRYPOINT ["myGoProgram"] # or ENTRYPOINT ["/usr/local/bin/myGoProgram"]