Dockerfile - set ENV to result of command

后端 未结 6 1210
傲寒
傲寒 2020-12-02 15:17

Is it possible to set a docker ENV variable to the result of a command? Like:

ENV MY_VAR whoami

i want MY_VAR to get the value \"root\" or

相关标签:
6条回答
  • 2020-12-02 15:34

    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.

    0 讨论(0)
  • 2020-12-02 15:35

    This answer is a response to @DarkSideF,

    The method he is proposing is the following, in Dockerfile :

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

    ( adding an export in the /etc/bash.bashrc)

    It is good but the environment variable will only be available for the process /bin/bash, and if you try to run your docker application for example a Node.js application, /etc/bash.bashrc will completely be ignored and your application won't have a single clue what SECRET_KEY_BASE is when trying to access process.env.SECRET_KEY_BASE.

    That is the reason why ENV keyword is what everyone is trying to use with a dynamic command because every time you run your container or use an exec command, Docker will check ENV and pipe every value in the process currently run (similar to -e).

    One solution is to use a wrapper (credit to @duglin in this github issue). Have a wrapper file (e.g. envwrapper) in your project root containing :

    #!/bin/bash
    export SECRET_KEY_BASE="$(openssl rand -hex 64)"
    export ANOTHER_ENV "hello world"
    $*
    

    and then in your Dockerfile :

    ...
    COPY . .
    RUN mv envwrapper /bin/.
    RUN chmod 755 /bin/envwrapper
    CMD envwrapper myapp
    
    0 讨论(0)
  • 2020-12-02 15:41

    Not sure if this is what you were looking for, but in order to inject ENV vars or ARGS into your .Dockerfile build this pattern works.

    in your my_build.sh:

    echo getting version of osbase image to build from
    OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')
    
    echo building docker
    docker build -f \
    --build-arg ARTIFACT_TAG=$OSBASE \
    PATH_TO_MY.Dockerfile \
    -t my_artifact_home_url/bucketname:$TAG .
    

    for getting an ARG in your .Dockerfile the snippet might look like this:

    FROM scratch
    ARG ARTIFACT_TAG
    FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
    

    alternatively for getting an ENV in your .Dockerfile the snippet might look like this:

    FROM someimage:latest
    ARG ARTIFACT_TAG
    ENV ARTIFACT_TAG=${ARTIFACT_TAG}
    

    the idea is you run the shell script and that calls the .Dockerfile with the args passed in as options on the build.

    0 讨论(0)
  • 2020-12-02 15:45

    At this time, a command result can be used with RUN export, but cannot be assigned to an ENV variable.

    Known issue: https://github.com/docker/docker/issues/29110

    0 讨论(0)
  • 2020-12-02 15:48

    As an addition to DarkSideF answer.

    You should be aware that each line/command in Dockerfile is ran in another container.

    You can do something like this:

    RUN export bleah=$(hostname -f);echo $bleah;
    

    This is run in a single container.

    0 讨论(0)
  • 2020-12-02 15:52

    As an addition to @DarkSideF's answer, if you want to reuse the result of a previous command in your Dockerfile during in the build process, you can use the following workaround:

    1. run a command, store the result in a file
    2. use command substitution to get the previous result from that file into another command

    For example :

    RUN echo "bla" > ./result
    RUN echo $(cat ./result)
    

    For something cleaner, you can use also the following gist which provides a small CLI called envstore.py :

    RUN envstore.py set MY_VAR bla
    RUN echo $(envstore.py get MY_VAR)
    

    Or you can use python-dotenv library which has a similar CLI.

    0 讨论(0)
提交回复
热议问题