简体   繁体   中英

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

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.

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.

I wanted to set an ENV or LABEL variable from a computation in the Dockerfile, eg to make some computed installation options visible in docker inspect .

There does not seem to be any way to do that, and this issue suggests that it's a security design choice.

A Dockerfile can set an ENV variable to $X , ${X:-default} , or ${X:+substitute} where that $X must be another ENV or ARG variable.

A single RUN command can set and use shell variables, but that goes away at the end of the RUN command when that container layer shuts down.

A RUN command can write computed data into files, but the Dockerfile still can't get that data into an ENV or LABEL even if the file is ~/.bashrc . (File contents can, of course, be used by code running in the Container.)

The build can at least RUN echo $X to record choices to the build log -- unless that step comes from the build cache, in which case the RUN step doesn't run.

Please do correct me if there's a way out.

Partially connected to question. If one wants to use the result of some command later on it is possible within single RUN statement as follows:

RUN CUR_DIR=`pwd` && \
    echo $CUR_DIR

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM