Add different condition in Dockerfile [5 Methods]


Docker

Different methods to add condition in Dockerfile

In this article, we will be learning about various methods to add conditions in Dockerfile.

When we create a Docker image, the best practice is to not hardcode any value in the dockerfile and it has to be passed dynamically to the docker build command while building the image.

Also, while creating the docker container, it is best to pass or set the Environment variable so that the container as a whole or the application within the docker container can access it.

This is made possible, by using the two variables inside the dockerfile namely, ARG and ENV.

Let us take a look at the scenarios, where these variables can fit in appropriately:

  1. Variable ARG: This variable can be used while building the docker image. This means that the variable is accessible only while creating the docker image and NOT accessible for the docker container.
  2. Variable ENV: This variable can be used by the container and it has the default value and it can be overwritten while creating the containers.

Let us understand how to use these variables with an example:

Case 1:

FROM ubuntu
ARG VER1=v10.0.0
ENV VER2=v20.0.0
RUN echo $VER1
RUN echo $VER2

Build the docker by passing an argument and notice that our container uses the ENV version from input argument while takes ARG version from the Dockerfile. So this confirms that ENV variable can be overwritten using input build argument but ARG value can not be overwritten.

Output:

docker build --build-arg VER1=v2.1.0 --build-arg VER2=v10.0.0 .

Add different condition in Dockerfile [5 Methods]

 

Method 1: Docker file if else

Suppose that you have a build system and you have to install Grunt or Gulp. So you have the dockerfile which has installation instructions for both. However, you don't want to install both of them and you have to decide on the package based on the condition. So, what would be the way to do it inside dockerfile?

So, there are two ways to do this. Let's check them out.

Option 1:

Add the condition in the RUN command as shown below:

RUN if grep -q "gulp" package.json; then echo succeed; fi 

Option 2:

Use the shell script. Below is the sample code to do this:

if [ "${BUILD_TOOL}" = "GRUNT" ]; then
echo "GRUNT setup";
echo "Done GRUNT setup";
elif [ "${BUILD_TOOL}" = "GULP" ]; then
echo "GULP setup";
echo "Done GULP setup";
fi

Copy the above shell script inside the dockerfile and run the below command which builds the image based on the argument specified.

FROM centos:centos7
ARG BUILD_TOOL
COPY setup.sh /setup.sh
RUN ./setup.sh
RUN rm /setup.sh

Command:

docker build --build-arg BUILD_TOOL=GULP . (or GRUNT)

Now, let us touch upon various other methods in detail that can help us implement the conditions in the dockerfile.

The below example takes the arguments while creating the docker image.

The if-else condition is written inside the dockerfile and the arguments are passed while building the docker image.

 

Method 2: Docker file if else with arg conditions

Below is the dockerfile which takes the argument and checks if the argument is passed or not and runs appropriately depending on the condition specified.

Dockerfile:

FROM centos:7
ARG argument
RUN \
if [[ -z "${argument}" ]] ; \
then echo ***Argument is not provided*** ; \
else \
echo ***Argument is ${argument}*** ; \
fi

 

Output:

Below is the output when the above-mentioned dockerfile is run by passing the arguments

docker build -t test_image -build-arg argument=100 .
Step 1/3 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/3 : ARG argument
 ---> Using cache
 ---> ffedfa347c83
Step 3/3 : RUN 	if [[ -z "${argument}" ]] ; 		then echo ***Argument is not provided*** ; 	else 		echo ***Argument is ${argument}*** ; 	fi
 ---> Running in 5ef5b781c633
***Argument is 100***
Removing intermediate container 5ef5b781c633
 ---> 269bacbed525
Successfully built 269bacbed525
Successfully tagged test_image:latest

In the above screenshot, you can notice that when the docker was built by passing the argument, the code inside the “else” condition got executed and printed in the console.

Now, let us build the dockerfile without passing the argument using the below command

Output:

docker build -t test_image .
Step 1/3 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/3 : ARG argument
 ---> Using cache
 ---> ffedfa347c83
Step 3/3 : RUN 	if [[ -z "${argument}" ]] ; 		then echo ***Argument is not provided*** ; 	else 		echo ***Argument is ${argument}*** ; 	fi
 ---> Using cache
 ---> a65d38e0c929
Successfully built a65d38e0c929
Successfully tagged test_image:latest

In the above screenshot, you can notice that when docker was built without passing the argument, the code inside the “if” condition got executed.

 

Method 3: Test input arguments in Docker fil

In this method, let us write a shell script which checks if the argument is passed or not using the “test” command.

Further, lets us copy this shell script in the dockerfile and build it.

Shell script:

#!/bin/bash -x

if test -z $1 ; then
    echo "The argument is empty"
else
    echo "The argument is not empty: $1"
fi

Dockerfile:

FROM centos:7
ARG argument

COPY script.sh /home/script.sh
RUN chmod u+x /home/script.sh && /home/script.sh $argument

Output:

Build the docker by passing the argument and check the results!!

docker build -t bash_image:1.0 –build-arg argument=80 .

Add different condition in Dockerfile [5 Methods]

In the above screenshot, you can notice that when the docker was built by passing the argument, the code inside the “else” condition got executed and printed in the console.

Build the docker without passing the argument and see that the else condition got executed in this case.

Output:

docker build -t bash_image:1.0 .

Add different condition in Dockerfile [5 Methods]

In the above screenshot, you can notice that when docker was built without passing the argument, the code inside the “if” condition got executed.

 

Method 4: Using ENV and ARG variable

Let us now use the ENV variable along with the ARG variable in the dockerfile.

Notice that the values passed as an environment will always persist.

Shell script:

#!/usr/bin/env sh

if [ -z "$env_argument" ]; then
    echo "No Parameters passed..."
else
    echo "Parameter passed..." $env_argument
fi

Dockerfile:

FROM centos:7

ARG argument=""
ENV env_argument=$argument

COPY test_script.sh /home
RUN chmod +x /home/test_script.sh && /home/test_script.sh

In the below screenshot, you can notice that when the docker was built by passing the argument, the code inside the “else” condition got executed and printed in the console.

Output:

docker build -t test —build-arg argument=”Hello,How are you” .

Add different condition in Dockerfile [5 Methods]

In the below screenshot, you can notice that when docker was built without passing the argument, the code inside the “if” condition got executed.

Output:

docker build -t test .

Add different condition in Dockerfile [5 Methods]

One important thing to note is whenever we use the conditional logic in the dockerfile, it is essential to build the dockerfile each time as we use the build-arg and it won't be cached.

Due to this, adding conditional logic in dockerfile slows down the build process.

 

Method 5: Conditional Dockerfile without bash

Here is one more alternative which uses a single dockerfile and avoids bash. Let's take a look!

Dockerfile:

ARG argument
ARG ENV

FROM centos:7 AS base
RUN echo "using centos as base image"

FROM base AS branch-version-1
RUN echo "seting VAR=TRUE"
ENV VAR=TRUE

FROM base AS branch-version-2
RUN echo "setting VAR=FALSE"
ENV VAR=FALSE

FROM branch-version-${argument} AS final
RUN echo "Varibale is equal to ${VAR}"

In this case we will pass input argument as 1 in which case the VAR value must be set as TRUE based on our conditions.

Output:

docker build -t multiline:1.0 --build-arg argument=1  .

Add different condition in Dockerfile [5 Methods]

In this case we will pass input argument as 2 in which case the VAR value must be set as FALSE based on our conditions.

Output:

docker build -t multiline:1.0 --build-arg argument=2 .

Add different condition in Dockerfile [5 Methods]

 

Conclusion

In this article, we have learnt about adding conditions in Dockerfile. I hope this article makes it clear to you and I suggest everyone try it out yourself.

In case you have any doubts, please feel free to add your questions in the comment section below and I shall try to respond at the earliest.

Happy learning!!

 

References

https://stackoverflow.com/questions/43654656/dockerfile-if-else-condition-with-external-arguments
https://docs.docker.com/build/building/multi-stage/
https://stackoverflow.com/questions/37057468/conditional-env-in-dockerfile

 

Deepak Prasad

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment