ARG substitution in RUN command not working for Dockerfile

DockerDockerfile

Docker Problem Overview


In my Dockerfile I have the following:

ARG a-version
RUN wget -q -O /tmp/alle.tar.gz http://someserver/server/$a-version/a-server-$a-version.tar.gz && \
    mkdir /opt/apps/$a-version

However when building this with:

--build-arg http_proxy=http://myproxy","--build-arg a-version=a","--build-arg b-version=b"

Step 10/15 : RUN wget... is shown with $a-version in the path instead of the substituted value and the build fails.

I have followed the instructions shown here but must be missing something else.

> My questions is, what could be causing this issue and how can i solve > it?

Docker Solutions


Solution 1 - Docker

Another thing to be careful about is that after every FROM statements all the ARGs get collected and are no longer available. Be careful with multi-stage builds.

You can reuse ARG with omitted default value inside FROM to get through this problem:

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

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

Solution 2 - Docker

Don't use - in variable names.

Docker build will always show you the line as is written down in the Dockerfile, despite the variable value.

So use this variable name a_version:

ARG a_version

See this example:

Dockerfile:

FROM alpine

ARG a_version
RUN echo $a_version

Build:

$ docker build . --build-arg a_version=1234
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM alpine
 ---> a41a7446062d
Step 2/3 : ARG a_version
 ---> Running in c55e98cab494
 ---> 53dedab7de75
Removing intermediate container c55e98cab494
Step 3/3 : RUN echo $a_version                <<< note this <<
 ---> Running in 56b8aeddf77b
1234                                          <<<< and this <<
 ---> 89badadc1ccf
Removing intermediate container 56b8aeddf77b
Successfully built 89badadc1ccf

Solution 3 - Docker

I had the same problem using Windows containers for Windows.

Instead of doing this (Which works in linux containers)

FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"

You need to do this

FROM mcr.microsoft.com/windows/servercore
ARG TARGETPLATFORM
RUN echo "I'm building for %TARGETPLATFORM%"

Just change the variable resolution according to the OS.

Solution 4 - Docker

I spent much time to have the argument substitution working, but the solution was really simple. The substitution within RUN needs the argument reference to be enclosed in double quotes.

ARG CONFIGURATION=Debug
RUN dotnet publish "Project.csproj" -c "$CONFIGURATION" -o /app/publish

Solution 5 - Docker

The only way I was able to substitute an ARG in a Windows Container was to prefix with $env:, as mentioned here.

An example of my Dockerfile is below. Notice that the ARG PAT is defined after the FROM so that it's in scope for its use in the RUN nuget sources add command (as Hongtao suggested). The only successful way I found to supply the personal access token was using $env:PAT

FROM mcr.microsoft.com/dotnet/framework/sdk:4.7.2 AS build
WORKDIR /app

ARG PAT

# copy csproj and restore as distinct layers
COPY *.sln .
COPY WebApi/*.csproj ./WebApi/
COPY WebApi/*.config ./WebApi/
RUN nuget sources add -name AppDev -source https://mysource.pkgs.visualstudio.com/_packaging/AppDev/nuget/v2 -username usern -password $env:PAT
RUN nuget restore

# copy everything else and build app
COPY WebApi/. ./WebApi/
WORKDIR /app/WebApi
RUN msbuild /p:Configuration=Release


FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2 AS runtime
WORKDIR /inetpub/wwwroot
COPY --from=build /app/WebApi/. ./

The actual Docker command looks like this:

docker build --build-arg PAT=mypatgoeshere -t webapi .

Solution 6 - Docker

I had the same problem accessing build-args in my RUN command. Turns out that the line containing the ARG definition should not be the first line. The working Dockerfile snippet looks like this:

FROM centos:7
MAINTAINER xxxxx

ARG SERVER_IPS

Earlier, I had placed the ARG definition as the first line of Dockerfile . My docker version is v19.

Solution 7 - Docker

For me it was argument's order:

docker build . -f somepath/to/Dockerfile --build-arg FOO=BAR

did not work, but:

docker build --build-arg FOO=BAR . -f somepath/to/Dockerfile

did.

Solution 8 - Docker

There are many answers, which make sense. But the main thing is missed.

The way, how to use build arguments depends on the base image.

  • For Linux image, it will work with $ARG
  • For Windows, depending on image, it can be either $env:ARG(e.g. for mcr.microsoft.com/dotnet/framework/sdk:4.8) or %ARG% (e.g. for mcr.microsoft.com/windows/nanoserver:1809)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3139545View Question on Stackoverflow
Solution 1 - DockerHongtao YangView Answer on Stackoverflow
Solution 2 - DockerRobertView Answer on Stackoverflow
Solution 3 - DockerJustin LessardView Answer on Stackoverflow
Solution 4 - DockerOlegView Answer on Stackoverflow
Solution 5 - DockernbroszView Answer on Stackoverflow
Solution 6 - DockerBinita BharatiView Answer on Stackoverflow
Solution 7 - DockerpbnView Answer on Stackoverflow
Solution 8 - DockerAntonView Answer on Stackoverflow