28

I've only seen examples of using COPY to copy files between stages of a multi stage Dockerfile, but is there a way to simply copy an ENV variable? My use case is to start out with a git image to just to get the commit hash that will be part of the build. The image I'm later building with hasn't got git.

I realise I could just pipe out the git hash to a file and use COPY but I'm just wondering if there's a cleaner way?

isapir
  • 21,295
  • 13
  • 115
  • 116
Viktor Hedefalk
  • 3,572
  • 3
  • 33
  • 48

3 Answers3

36

You got 3 options: The "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.

Jinxmcg
  • 1,830
  • 1
  • 21
  • 24
  • 6
    Just be aware if you go with the "base container" route if you expose any credentials in layers in that first stage, they will show up in the final image, which is almost certainly not what you want. – icfantv Nov 07 '20 at 04:46
2

The important part to remember is to re-declare the ARG without a default in each stage:

#### Declare Global build arg
ARG SOME_GLOBAL_ARG=some-value

###  Build Stage 1
FROM base-image AS stage-1

##   inherit global arg
ARG SOME_GLOBAL_ARG

##   use global arg to set env var
ENV VAR1=${SOME_GLOBAL_ARG}


###  Build Stage 2
FROM stage-1 AS stage-2

##   inherit global arg
ARG SOME_GLOBAL_ARG

##   use global arg to set env var
ENV VAR1=${SOME_GLOBAL_ARG}
isapir
  • 21,295
  • 13
  • 115
  • 116
0

Share variables between stages in Dockerfile:

  1. save the variables/ENVs to a file in the 1st stage: echo $runDeps > $DESTDIR/runtime.deps
  2. copy files from the 1st stage to the 2nd stage: $DESTDIR/runtime.deps
  3. restore the value from the file in the 2nd stage: RUN apk add --no-cache --virtual .run-deps `cat /runtime.deps` gnutls-utils iptables libnl3 readline gettext libintl
Iceberg
  • 2,744
  • 19
  • 19