korda
korda

Reputation: 822

Dockerfile - evaluate env variable at build time

Because bin name of app I'm putting in container can change (docker build is part of larger build and it's easy for me to pass correct name from one build to another) I want to do something like this:

ENTRYPOINT ["$PATH_TO_BIN"]

But since there is no shell to evaluate this will normally fail. In theory I could go for

ENTRYPOINT $PATH_TO_BIN

But in this case I cannot pass any arguments when doing run.

Is it somehow possible to use exec form and evaluate args or env variables during the build (so there is no need for shell at runtime?)

Upvotes: 0

Views: 2457

Answers (2)

Cau
Cau

Reputation: 1919

If you're using the latest version of Docker Engine you can add this in your Dockerfile:

ARG PATH_TO_BIN

and then do this:

docker build --build-arg PATH_TO_BIN=/usr/bin/

See more at documentation

Upvotes: 1

Tarun Lalwani
Tarun Lalwani

Reputation: 146630

This quite possible. The problem is that your trying to execute the command directly. Instead what you need to do is, create a entrypoint.sh and let it execute. That script can determine what it needs to do based on environment variables.

Consider the below Dockerfile

FROM centos:7.2.1511
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["this","is", "tarun"]

and content of the entrypoint.sh are as below

#!/usr/bin/env sh

_load() {
   CMD=""
   if [ ! -z "$ENTRYPOINT" ]; then
      CMD=$ENTRYPOINT
   fi

   if [ "$#" -gt 0 ]; then
      CMD="$CMD $@"
   elif [ ! -z $COMMAND ]; then
      CMD="$CMD $COMMAND"
   fi

   echo "Executing - $CMD"
   exec $CMD
}

_load $@

The script does nothing but check if a environment variable $ENTRYPOINT or $COMMAND was passed, or both were passed, or command from docker run was passed. Based on below priority order it runs the command

  • ENTRYPOINT + RUN PARAMETERS - Combine both and execute
  • ENTRYPOINT + COMMAND - Combine both and execute
  • MISSING $COMMAND - Run $ENTRYPOINT
  • MISSING $ENTRYPOINT - Run $COMMAND

Now to test it

$ docker run -e ENTRYPOINT=/bin/echo test my name "is XYZ"
Executing - /bin/echo my name is XYZ
my name is XYZ

The script may not be 100% perfect, but I just created it to demonstrate the idea

If you need a simple entrypoint.sh then you can even replace it with below content

exec $ENTRYPOINT $@

This also would work.

Upvotes: 0

Related Questions