Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uninitialized ARG variables do not inherit default value from ARGs declared at the top of the Dockerfile before a FROM #26

Closed
rcjsuen opened this issue May 13, 2018 · 0 comments
Assignees
Labels

Comments

@rcjsuen
Copy link
Owner

rcjsuen commented May 13, 2018

It seems like I had missed a part of the specification in the Docker documentation. I had thought that ARG instructions at the top of the Dockerfile were completely disconnected from any ARG instruction after the first FROM. But it seems like you can actually use the default value defined by an ARG at the top of the Dockerfile if you simply redeclare an uninitialized ARG within a build stage.

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:

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

Because of this mistake, the following code will print out the wrong output.

import { DockerfileParser } from 'dockerfile-ast';

const content =
`ARG ver=latest
FROM busybox:$ver
ARG ver
RUN echo $ver
FROM busybox:$ver
ARG ver=override
RUN echo $ver
FROM busybox:$ver
RUN echo $ver`;

let dockerfile = DockerfileParser.parse(content);
let from1 = dockerfile.resolveVariable("ver", 1);
let from2 = dockerfile.resolveVariable("ver", 4);
let from3 = dockerfile.resolveVariable("ver", 7);
let run1 = dockerfile.resolveVariable("ver", 3);
let run2 = dockerfile.resolveVariable("ver", 6);
let run3 = dockerfile.resolveVariable("ver", 8);

console.log(from1 + "\t" + (from1 === "latest"));
console.log(from2 + "\t" + (from2 === "latest"));
console.log(from3 + "\t" + (from3 === "latest"));
console.log(run1 + "\t" + (run1 === "latest"));
console.log(run2 + "\t" + (run2 === "override"));
console.log(run3 + "\t" + (run3 === undefined));

The first RUN instruction incorrectly resolves its $ver variable reference to a null.

latest  true
latest  true
latest  true
null    false
override        true
undefined       true

The same Dockerfile will echo out latest when built.

$ docker build .
Sending build context to Docker daemon  1.693MB
Step 1/9 : ARG ver=latest
Step 2/9 : FROM busybox:$ver
latest: Pulling from library/busybox
f70adabe43c0: Pull complete
Digest: sha256:58ac43b2cc92c687a32c8be6278e50a063579655fe3090125dcb2af0ff9e1a64
Status: Downloaded newer image for busybox:latest
 ---> 8ac48589692a
Step 3/9 : ARG ver
 ---> Running in 3b6006d4df7b
Removing intermediate container 3b6006d4df7b
 ---> f6c504c4e2d5
Step 4/9 : RUN echo $ver
 ---> Running in 6f8dd526ada2
latest
Removing intermediate container 6f8dd526ada2
 ---> 5be775c1e7eb
Step 5/9 : FROM busybox:$ver
 ---> 8ac48589692a
Step 6/9 : ARG ver=override
 ---> Running in 910172a45e7b
Removing intermediate container 910172a45e7b
 ---> dd5eaaf8e863
Step 7/9 : RUN echo $ver
 ---> Running in 8d2d612cfc93
override
Removing intermediate container 8d2d612cfc93
 ---> 4abd6a0ad69d
Step 8/9 : FROM busybox:$ver
 ---> 8ac48589692a
Step 9/9 : RUN echo $ver
 ---> Running in b2bb05a9b6c6

Removing intermediate container b2bb05a9b6c6
 ---> 0d3c30c049e0
Successfully built 0d3c30c049e0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant