Dockerfile Reference – ARG Instruction

Hello Everyone,
Hope you’re doing well. Till now in this series we’ve explored various instructions which are used in Dockerfile. In this article we’ll explore about ARG instruction in detail. For other articles of this series please refer index page.

ARG Instruction defines a variable which user can pass to builder runtime using docker build command. Dockerfile may contain one or more ARG Instructions. Syntax,

ARG <name>[=<default value>]

User can provide / override given value using --build-arg <variable>=<value>
  • You can define as many ARGs as you want.
  • If a variable is not defined and you pass the same as build-arg, you’ll get warning – “[Warning] One or more build-args [<variable-name>] were not consumed.
  • It is not recommanded to pass credentials and secrets using build-time variables, they are visible to user and can be found using docker history command.
  • Optionally variable can be assigned a default value, if no build-time value will be passed, default value will be considered.
  • Scope : build-time variable is valid from the line it was defined and it is valid through the build stage. If variable is used prior to it’s declaration, it will be evalulated as empty.
  • In order to use variable in multi-stage environment, user needs to declare in both the stages.
# Using multiple variables
FROM busybox
ARG user
ARG build=1
USER $user
...

# Using variable in multi-stage build
FROM busybox as base
ARG SETTINGS
..

FROM busybox
ARG SETTINGS
..

Using ENV and ARG
User can use both ENV and ARG for creating environment variable and build-time variable respectively. But if user creates both variables using same name, ENV variable will always override ARG variable. Let’s try, consider below code

FROM ubuntu
ENV IMG_VER=v1.0.0
ARG IMG_VER
RUN echo $IMG_VER

If I run above code using - docker build -t test-arg-env --build-arg IMG_VER=v2.0.1 .

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM ubuntu
 ---> f63181f19b2f
Step 2/4 : ENV IMG_VER=v1.0.0
 ---> Running in 73f0784de995
Removing intermediate container 73f0784de995
 ---> 5f0d481e3acd
Step 3/4 : ARG IMG_VER
 ---> Running in 89681ae76284
Removing intermediate container 89681ae76284
 ---> 7ac03c45b330
Step 4/4 : RUN echo $IMG_VER
 ---> Running in 2e7962992bc9
v1.0.0
Removing intermediate container 2e7962992bc9
 ---> 7b9a5aec37b7
Successfully built 7b9a5aec37b7
Successfully tagged test-arg-env:latest

Moreover as we already know ENV variable persists it’s value even after build is done, unlike ARG variable which is available only thoughout the build.

Predefined ARGS
Docker has a predefined set of ARG variables which you can use without declaring them. To use these variables directly pass them using command line argument.

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • FTP_PROXY
  • ftp_proxy
  • NO_PROXY
  • no_proxy

By default, these predefined variables are excluded from docker history to reduce the security risk – like if you have http proxy – –build-arg HTTP_PROXY=http://user:pass@proxy.example.com – then it will not be cached.

If you want to change this behaviour, simply declare the variable in Dockerfile and your command will be cached.

Global build-time variables
Starting version 18.09, Docker supports a new backend for executing your build. If you enable the same below global variables will be available to you.

  • TARGETPLATFORM
  • TARGETOS
  • TARGETARCH
  • TARGETVARIANT
  • BUILDPLATFORM
  • BUILDOS
  • BUILDARCH
  • BUILDVARIANT

In order to use these variables, just declare them in Dockerfile and it will be available to you.

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

Impact on build caching
As we know, docker build uses caching so any change in given instructions, creates a “cache miss” and instructions are build again. So any change in build-time variable will trigger “cache miss” and instructions will be executed again. let’s understand it using example,

# Use-Case 1
FROM ubuntu
ARG IMG_VER
RUN echo hello

# Execution Command - docker build -t test-arg-env --build-arg IMG_VER=v2.0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> f63181f19b2f
Step 2/3 : ARG IMG_VER
 ---> Running in 2a8c3f5f3c1c
Removing intermediate container 2a8c3f5f3c1c
 ---> 2925506873e3
Step 3/3 : RUN echo hello
 ---> Running in 4a08d12bc45a
hello
Removing intermediate container 4a08d12bc45a
 ---> d1130acd6dcc
Successfully built d1130acd6dcc
Successfully tagged test-arg-env:latest

# Executing Command - docker build -t test-arg-env --build-arg IMG_VER=v2.0.2 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> f63181f19b2f
Step 2/3 : ARG IMG_VER
 ---> Using cache
 ---> 2925506873e3
Step 3/3 : RUN echo hello
 ---> Running in 0ce1bd6ce0cd
hello
Removing intermediate container 0ce1bd6ce0cd
 ---> 39a3af04cb8b
Successfully built 39a3af04cb8b
Successfully tagged test-arg-env:latest

# Use-Case 2
FROM ubuntu
ARG IMG_VER
RUN echo $IMG_VER

# Executing Command - docker build -t test-arg-env --build-arg IMG_VER=v2.0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> f63181f19b2f
Step 2/3 : ARG IMG_VER
 ---> Using cache
 ---> 2925506873e3
Step 3/3 : RUN echo $IMG_VER
 ---> Running in 988b05e5a7be
v2.0.1
Removing intermediate container 988b05e5a7be
 ---> 20035442272d
Successfully built 20035442272d
Successfully tagged test-arg-env:latest

# Executing Command - docker build -t test-arg-env --build-arg IMG_VER=v2.0.2 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> f63181f19b2f
Step 2/3 : ARG IMG_VER
 ---> Using cache
 ---> 2925506873e3
Step 3/3 : RUN echo $IMG_VER
 ---> Running in a7432736f748
v2.0.2
Removing intermediate container a7432736f748
 ---> 1abfaa3f359f
Successfully built 1abfaa3f359f
Successfully tagged test-arg-env:latest

That’s it for this article, hope it provides you detailed understanding for ARG instruction. Please let me know if you have any query / suggestion in comment section. If you want to refer similar articles, please visit index page.

Reference : https://docs.docker.com

Sanket Modi

Working in Information Technology since 2012. Started my career as Java Developer and now working in multiple different technologies like nodejs, Python, Docker, Kubernetes, Azure etc. I like to explore new technologies and read books.

You may also like...

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: