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?
2
Answers
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.
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
My experiments were on Linux where I used this Dockerfile
and got this output
So if you have an ENV statement, you can set the environment variable to the value from the build argument.