cancel
Showing results for 
Search instead for 
Did you mean: 
AlessandraS
Flight Engineer
Flight Engineer
  • 128 Views

DO188 - Chapter 4 - 4.3 Build Images with Advanced Containerfile Instructions - ARG/ENV instructions

Jump to solution

Hi, 
I tried to build and run this containerfile to test ARG and ENV instructions.

AlessandraS_1-1758812749286.png

I built the image providing the --build-arg flag for VERSION and BIN_DIR and then ran the container (see image below).

I expected to find the Environment variable of the running container valued this way:

VERSION = 1.16.8 and BIN_DIR = /usr/local/bin/

while, as you can see below VERSION = 5 and BIN_DIR=/www (but these are the values specified in the --build-arg flag).   What's wrong in my tests?

Thanks

AlessandraS_0-1758812706355.png

3 Solutions

Accepted Solutions
ARoumiantsev
Flight Engineer
Flight Engineer
  • 105 Views

Hi @AlessandraS 

Try build with only one of your --build-arg and you will see a difference.  In your case, when you define both --build-args, ENV variables will get thier values from ARG values ( --build-arg ), but not default in ENV instruction.

Good luck 

View solution in original post

Chetan_Tiwary_
Community Manager
Community Manager
  • 95 Views

@AlessandraS When you use --build-arg during the build, it actually overrides any default values you set in your ENV ...${VAR:-default} expression. That s exactly how Docker’s build arguments are supposed to work, so this behavior is expected. The default only kicks in when no --build-arg is given or when the ARG is undefined.

@Travis do you want to weigh in here ?

 

https://docs.docker.com/build/building/variables/ 

View solution in original post

Travis
Moderator
Moderator
  • 79 Views

@AlessandraS -

I would say @Chetan_Tiwary_ did an excellent job explaining. Essentially what you are doing with this line 

ENV VERSION=${VERSION:-1.16.8} \
    BIN_DIR=${BIN_DIR:-/usr/local/bin/}

is setting environment variables. In this instance, you have defaults set of 1.16.8 and /usr/local/bin. However, as part of the build process, you specified build arguments which would override the default values on the environment line and that is exactly what you saw.

Another interesting thing you could do, in addition to what @ARoumiantsev suggested (changing build arguments and only providing one value or providing no values) is to use a "-e" in the podman run command to provide runtime environment variables into the container. Use something that is neither in your Containerfile nor the podman build with arguments and see how that changes things. 

The real thing here that might not be clear ...

ARG - provides a user the ability to use build-time arguments as variables for a container allowing custom containers to be built with a single Containerfile just by changing variables.

ENV - provides a user the ability to provide runtime arguments as environment variables customizing the running container but not the container image.

Using both together allows a Container image to be customized at build time, at run time, or a combination of the two so you have the best of both worlds.

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training

View solution in original post

6 Replies
ARoumiantsev
Flight Engineer
Flight Engineer
  • 106 Views

Hi @AlessandraS 

Try build with only one of your --build-arg and you will see a difference.  In your case, when you define both --build-args, ENV variables will get thier values from ARG values ( --build-arg ), but not default in ENV instruction.

Good luck 

Chetan_Tiwary_
Community Manager
Community Manager
  • 96 Views

@AlessandraS When you use --build-arg during the build, it actually overrides any default values you set in your ENV ...${VAR:-default} expression. That s exactly how Docker’s build arguments are supposed to work, so this behavior is expected. The default only kicks in when no --build-arg is given or when the ARG is undefined.

@Travis do you want to weigh in here ?

 

https://docs.docker.com/build/building/variables/ 

Travis
Moderator
Moderator
  • 80 Views

@AlessandraS -

I would say @Chetan_Tiwary_ did an excellent job explaining. Essentially what you are doing with this line 

ENV VERSION=${VERSION:-1.16.8} \
    BIN_DIR=${BIN_DIR:-/usr/local/bin/}

is setting environment variables. In this instance, you have defaults set of 1.16.8 and /usr/local/bin. However, as part of the build process, you specified build arguments which would override the default values on the environment line and that is exactly what you saw.

Another interesting thing you could do, in addition to what @ARoumiantsev suggested (changing build arguments and only providing one value or providing no values) is to use a "-e" in the podman run command to provide runtime environment variables into the container. Use something that is neither in your Containerfile nor the podman build with arguments and see how that changes things. 

The real thing here that might not be clear ...

ARG - provides a user the ability to use build-time arguments as variables for a container allowing custom containers to be built with a single Containerfile just by changing variables.

ENV - provides a user the ability to provide runtime arguments as environment variables customizing the running container but not the container image.

Using both together allows a Container image to be customized at build time, at run time, or a combination of the two so you have the best of both worlds.

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
AlessandraS
Flight Engineer
Flight Engineer
  • 22 Views

@Chetan_Tiwary_  Did you mean "The default only kicks in when no --build-arg is given and the ARG is undefined" ?

0 Kudos
Travis
Moderator
Moderator
  • 14 Views

@AlessandraS -

I know you asked @Chetan_Tiwary_ , but I feel I can confidently answer that that is indeed what was meant.

Variables always need defined. So, if you are building a container image and there are ARG variables that aren't defined, it would typically fail because there would be a section that would try to access an undefined variable. The default setting for the "ENV" for building of the image would kick in, and set the values so that the build could continue. 

You cannot proceed with building or running a container if there are undefined variables. The book and content the way it is worded might not be quite as clear, but to put things another way ... values must be set and known before you can continue.

I hate to bring this up as an example, but I'm going to anyways ... the MySQL and database containers get built from Container images. Often, users must specify the Database name, User passwords, and other things before the container can run. However, it is possible that if these were pre-built and predefined you could startup a very insecure container because a default known password would be used.

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
0 Kudos
AlessandraS
Flight Engineer
Flight Engineer
  • 38 Views

Thanks @Travis @Chetan_Tiwary_ @ARoumiantsev for all your explanations

0 Kudos
Join the discussion
You must log in to join this conversation.