Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a dockerfile argument in a RUN statement

I have the following Dockerfile, which works:

FROM someimage
ARG transform

COPY Web*.config /inetpub/wwwroot/
RUN powershell /Build/Transform.ps1 -xml "/inetpub/wwwroot/web.config" -xdt "/inetpub/wwwroot/web.debug.config"

However, I'd like to make the web.debug.config file an argument passed in when I build. So I've changed the last line to:

RUN powershell /Build/Transform.ps1 -xml "/inetpub/wwwroot/web.config" -xdt "/inetpub/wwwroot/${transform}"

When I do this, the ${transform} argument does not get interpolated and gets converted to an empty string. I've confirmed that the transform argument is getting passed in correctly, since I can do:

COPY ${transform} /inetpub/wwwroot/

...and the file gets copied. Is there some other way of interpolating arguments in a string using the RUN command?

I'm using Docker 18.03.1-ce on Windows 10.

like image 775
Mike Christensen Avatar asked May 31 '18 03:05

Mike Christensen


People also ask

How do I pass ARG in Dockerfile?

ARG instruction defines a variable that can be passed at build time. Once it is defined in the Dockerfile you can pass with this flag --build-arg while building the image. We can have multiple ARG instruction in the Dockerfile. ARG is the only instruction that can precede the FROM instruction in the Dockerfile.

Can an ARG variable on Dockerfile be used by the running container?

ARG are also known as build-time variables. They are only available from the moment they are 'announced' in the Dockerfile with an ARG instruction up to the moment when the image is built. Running containers can't access values of ARG variables.

How do I pass a variable in docker run?

Using –env, -e When we launch our Docker container, we can pass environment variables as key-value pairs directly into the command line using the parameter –env (or its short form -e). As can be seen, the Docker container correctly interprets the variable VARIABLE1.

Can you have both CMD and ENTRYPOINT in Dockerfile?

#6 Using ENTRYPOINT with CMD Still, they both can be used in your Docker file. There are many such cases where we can use both ENTRYPOINT and CMD. The thing is that you will have to define the executable with the ENTRYPOINT and the default parameters using the CMD command. Maintain them in exec form at all times.


1 Answers

Well, I found a solution that works but it's definitely not ideal. It appears variables simply aren't expanded in RUN statements (at least on Windows, haven't tried Linux). However, the COPY statement will expand them. So, I can copy my file to a temp file with a hard coded name, and then use that:

COPY ./ /inetpub/wwwroot/
COPY ${transform} /inetpub/wwwroot/Web.Current.config
RUN powershell -executionpolicy bypass /Build/Transform.ps1 -xml "/inetpub/wwwroot/web.config" -xdt "/inetpub/wwwroot/Web.Current.config"

In this particular situation, it works for me.

Update: Found another method that works

This is perhaps a better method using environment variables:

FROM someimage
ARG transform
ENV TransformFile ${transform}

COPY ./ /inetpub/wwwroot/
RUN powershell -executionpolicy bypass /Build/Transform.ps1 -xml "/inetpub/wwwroot/web.config" -xdt "/inetpub/wwwroot/$ENV:TransformFile"

In this case, Docker will evaluate the parameter transform and set it to the environment variable TransformFile. When I use it in the PowerShell script, it's no longer Docker that's evaluating the argument, but Powershell itself. Thus, the Powershell syntax for interpolating an environment variable must be used.

like image 198
Mike Christensen Avatar answered Oct 18 '22 11:10

Mike Christensen