Share variable in multi-stage Dockerfile: ARG before FROM not substituted

I'm writing a multi-stage Dockerfile for the darshan utils:

ARG DARSHAN_VER=3.1.6

FROM fedora:29 as build
RUN dnf install -y \
        gcc \
        make \
        bzip2 bzip2-devel zlib zlib-devel
RUN curl -O "ftp://ftp.mcs.anl.gov/pub/darshan/releases/darshan-${DARSHAN_VER}.tar.gz" \
    && tar ...


FROM fedora:29
COPY --from=build "/usr/local/darshan-${DARSHAN_VER}" "/usr/local/darshan-${DARSHAN_VER}"
...

I build it with docker build -t darshan-util:3.6.1 . and the error I get is:

Step 5/10 : RUN curl -O "ftp://ftp.mcs.anl.gov/pub/darshan/releases/darshan-${DARSHAN_VER}.tar.gz"     && tar ...

 ---> Running in 9943cce1669c
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
...
curl: (78) RETR response: 550
The command '/bin/sh -c curl -O "ftp://ftp.mcs.anl.gov/pub/darshan/releases/darshan-${DARSHAN_VER}.tar.gz"     && tar ...' returned a non-zero code: 78

I'd like to reuse the same ARG in both stages, so that I can define a default build variable just once. If I duplicate ARG in both stages, just below the two FROMs, it builds correctly.

What is the correct way to define a "global" multi-stage ARG variable with a default?


ARGs only last for the build phase of a single image. For the multistage, renew the ARG by simply stating:

ARG DARSHAN_VER

after your FROM instructions.

cf. https://docs.docker.com/engine/reference/builder/#arg

ARG DARSHAN_VER=3.1.6

FROM fedora:29 as build
ARG DARSHAN_VER
RUN dnf install -y \
        gcc \
        make \
        bzip2 bzip2-devel zlib zlib-devel
RUN curl -O "ftp://ftp.mcs.anl.gov/pub/darshan/releases/darshan-${DARSHAN_VER}.tar.gz" \
    && tar ...


FROM fedora:29
ARG DARSHAN_VER
COPY --from=build "/usr/local/darshan-${DARSHAN_VER}" "/usr/local/darshan-${DARSHAN_VER}"
...

Here are quotes from the documentation:

An ARG instruction goes out of scope at the end of the build stage where it was defined. To use an arg in multiple stages, each stage must include the ARG instruction.

https://docs.docker.com/engine/reference/builder/#scope

An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM. To use the default value of an ARG declared before the first FROM use an ARG instruction without a value inside of a build stage

https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact