7

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 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"]
Amin Karbas
  • 562
  • 1
  • 7
  • 16

1 Answers1

10

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"]
Jinxmcg
  • 1,830
  • 1
  • 21
  • 24
  • I know i can do that and that is what I've currently done. The thing is I want to use variables for this purpose. (The point is using variables somehow.) – Amin Karbas Feb 20 '19 at 22:23
  • I actually answered the question you said it was unanswered with the response to that https://stackoverflow.com/questions/52904847/how-do-i-copy-variables-between-stages-of-multi-stage-docker-build – Jinxmcg Feb 22 '19 at 01:32
  • Your answer over there seems doable/legit :) and I'll try it on Sunday. Thanks. – Amin Karbas Feb 22 '19 at 14:02
  • I will update this answer here too to mark it here as correct answer – Jinxmcg Feb 22 '19 at 20:51