Home > Back-end >  Docker multistage build doesn't pass arguments to second stage
Docker multistage build doesn't pass arguments to second stage

Time:02-06

I have dockerbuild file that contains from 2 stages

ARG DOTNET_VERSION=net48
ARG CONFIGURATION=Release
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build-env
ARG DOTNET_VERSION
ARG CONFIGURATION

RUN echo .Net version: $env:DOTNET_VERSION

FROM mcr.microsoft.com/windows/nanoserver:1809
ARG DOTNET_VERSION

RUN echo .Net version: $env:DOTNET_VERSION

I start it using next command: docker build -t test . --build-arg DOTNET_VERSION=net471 --no-cache

Output is:

Step 1/9 : ARG DOTNET_VERSION=net48
Step 2/9 : ARG CONFIGURATION=Release
Step 3/9 : FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build-env
 ---> c1e2ba0a9132
Step 4/9 : ARG DOTNET_VERSION
 ---> Running in 35ac4620bae3
Removing intermediate container 35ac4620bae3
 ---> 2000301c9b49
Step 5/9 : ARG CONFIGURATION
 ---> Running in 06b7c39a01b2
Removing intermediate container 06b7c39a01b2
 ---> 1591528894c8
Step 6/9 : RUN echo .Net version: $env:DOTNET_VERSION
 ---> Running in 6692bbe08eae
.Net
version:
net471
Removing intermediate container 6692bbe08eae
 ---> 7c4fa49a7732
Step 7/9 : FROM mcr.microsoft.com/windows/nanoserver:1809
 ---> 8572826a0d1a
Step 8/9 : ARG DOTNET_VERSION
 ---> Running in 3a1d9f759aaa
Removing intermediate container 3a1d9f759aaa
 ---> 74a6ccf7960f
Step 9/9 : RUN echo .Net version: $env:DOTNET_VERSION
 ---> Running in 13122b910b39
.Net version: $env:DOTNET_VERSION
Removing intermediate container 13122b910b39
 ---> 1c5b754b0b56
Successfully built 1c5b754b0b56

Why step 6 and step 9 results are different?

CodePudding user response:

This looks like it might be a bug.

When you have a build arg with the same name as an already existing environment variable, Docker will use the already set environment variable instead of the build arg.

The framework image you use already has an environment variable called DOTNET_VERSION, so you can't access the build arg value.

The solution is to name your build arguments something else. I've added a suffix _ARG here

ARG DOTNET_VERSION_ARG=net48
ARG CONFIGURATION=Release
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build-env
ARG DOTNET_VERSION_ARG
ARG CONFIGURATION

RUN echo .Net version: $env:DOTNET_VERSION_ARG

FROM mcr.microsoft.com/windows/nanoserver:1809
ARG DOTNET_VERSION_ARG

RUN echo .Net version: $env:DOTNET_VERSION_ARG

My experiments were on Linux where I used this Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0
ARG DOTNET_VERSION=no-arg
ARG DOTNET_VERSION_ARG=arg
RUN echo DOTNET_VERSION=$DOTNET_VERSION - DOTNET_VERSION_ARG=$DOTNET_VERSION_ARG
ENV DOTNET_VERSION=$DOTNET_VERSION_ARG
RUN echo DOTNET_VERSION=$DOTNET_VERSION

and got this output

DOTNET_VERSION=6.0.1 - DOTNET_VERSION_ARG=arg
DOTNET_VERSION=arg

So if you have an ENV statement, you can set the environment variable to the value from the build argument.

CodePudding user response:

I found the problem

If mcr.microsoft.com/windows/nanoserver:1809 image is used then arguments should be used in %arg% format.

If mcr.microsoft.com/dotnet/framework/sdk:4.8 image is used then arguments should be used in $env:arg format.

It is confusing and I haven't found where it is documented.

  •  Tags:  
  • Related