Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse a variable with the result of a command in DockerFile

I need to fill a variable in dockerfile with the result of a command

Like in bash var=$(date)

EDIT 1

date is a example. in my case i use FROM phusion/baseimage:0.9.17 so i want at each building use the last version so i use this curl -v --silent api.github.com/repos/phusion/baseimage-docker/tags 2>&1 | grep -oh 'rel-.*",' | head -1 | sed 's/",//' | sed 's/rel-//' ==> 0.9.17. but i don't know how i parse it in var with dockerfile for this result

ENV verbaseimage=curl...
FROM phusion/baseimage:$verbaseimage

RESULT

In my use case

FROM phusion/baseimage:latest

But the question remains unresolved for other case

like image 840
SilentT Avatar asked Oct 18 '15 17:10

SilentT


People also ask

What is ARG command in Dockerfile?

The ARG directive in Dockerfile defines the parameter name and defines its default value. This default value can be overridden by the --build-arg <parameter name>=<value> in the build command docker build .

What does Workdir in Dockerfile do?

The WORKDIR command is used to define the working directory of a Docker container at any given time. The command is specified in the Dockerfile. Any RUN , CMD , ADD , COPY , or ENTRYPOINT command will be executed in the specified working directory.

Can you pass arguments to Dockerfile?

Here is the Dockerfile using both ARG and ENV together to take the PORT as the build argument. Here is the app running on the port 3090. In this way, we can pass as many arguments as possible to pass as environment variables while building the image.

Can we use ls command in Dockerfile?

In order to list the Docker containers, we can use the “docker ps” or “docker container ls” command. This command provides a variety of ways to list and filter all containers on a particular Docker engine. Let's start by listing all the running containers.


2 Answers

I had same issue and found way to set environment variable as result of function by using RUN command in dockerfile.

For example i need to set SECRET_KEY_BASE for Rails app just once without changing as would when i run:

docker run  -e SECRET_KEY_BASE="$(openssl rand -hex 64)"

Instead it i write to Dockerfile string like:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

and my env variable available from root, even after bash login. or may be

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'

then it variable available in CMD and ENTRYPOINT commands

Docker cache it as layer and change only if you change some strings before it.

You also can try different ways to set environment variable.

like image 190
DarkSideF Avatar answered Nov 14 '22 22:11

DarkSideF


The old workaround is mentioned here (issue 2637: Feature request: expand Dockerfile ENV $VARIABLES in WORKDIR):

One work around that I've used, is to have a file in my context called "build-env". What I do is source it and run my desired command in the same RUN step. So for example:

build-env:

VERSION=stable

Dockerfile:

FROM radial/axle-base:latest
ADD build-env /build-env
RUN source build-env && mkdir /$VERSION
RUN ls /

But for date, that might not be as precise as you want.

Other workarounds are in issue 2022 "Dockerfile with variable interpolation".


In docker 1.9 (end of October 2015), you will have "support for build-time environment variables to the 'build' API (PR 9176)" and "Support for passing build-time variables in build context (PR 15182)".

docker build --build-arg=[]: Set build-time variables

You can use ENV instructions in a Dockerfile to define variable values. These values persist in the built image. However, often persistence is not what you want. Users want to specify variables differently depending on which host they build an image on.

A good example is http_proxy or source versions for pulling intermediate files. The ARG instruction lets Dockerfile authors define values that users can set at build-time using the ---build-arg flag:

$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

This flag allows you to pass the build-time variables that are accessed like regular environment variables in the RUN instruction of the Dockerfile.
Also, these values don't persist in the intermediate or final images like ENV values do.


so I want at each building use the last version so I use this

curl -v --silent api.github.com/repos/phusion/baseimage-docker/tags 2>&1 | grep -oh 'rel-.*",' | head -1 | sed 's/",//' | sed 's/rel-//' ==> 0.9.17. 

If you want to use the last version of that image, all you need to do is use the tag 'latest' with the FROM directive:

FROM phusion/baseimage:latest

See also "The misunderstood Docker tag: latest": it doesn't always reference the actual latest build, but in this instance, it should work.

If you really want to use the curl|parse option, use it to generate a Dockerfile with the right value (as in a template processed to generate the right file).
Don't try to use it directly in the Dockerfile.

like image 37
VonC Avatar answered Nov 14 '22 22:11

VonC