bashdockerdockerfiledocker-exec

Setting environment variable derived in container at runtime within a shell


I have custom entrypoint where a environment variable is exported. The value of the environment variable is constructed using two other variables provided at runtime.

Snippet from Dockerfile CMD ["bash", "/opt/softwareag/laas-api-server/entrypoint.sh"]. Snippet from entrypoint.sh

export URL="$SCHEME://$HOST:$PORT"
echo "URL:$URL"

Command docker run -e HOST="localhost" -e PORT="443" mycentos prints URL:localhost:443 as expected but the same variable appears to have lost the value when the following command is executed.

docker exec -ti <that-running-container-from-myimage> bash 
container-prompt> echo $URL
<empty-line>

Why would the exported variable appear to have lost the value of URL? What is getting lost here?


Solution

  • The environment variable will not persist across all bash session. when the container run it will only available in that entrypoint session but later it will not available if it set using export.

    docker ENV vs RUN export

    If you want to use across all session you should set them in Dockerfile.

    ENV SCHEME=http
    ENV HOST=example.com
    ENV PORT=3000
    

    And in the application side, you can use them together.also it will be available for all session.

    curl "${SCHEME}://${HOST}:${PORT}
    #
    Step 8/9 : RUN echo "${SCHEME}://${HOST}:${PORT}"
     ---> Running in afab41115019
    http://example.com:3000
    
    

    Now if we look into the way you are using, it will not work because

    export URL="$SCHEME://$HOST:$PORT"
    # only in this session
    echo "URL:$URL"
    # will be available for node process too but for this session only
    node app.js
    

    For example look into this Dockerfile

    FROM node:alpine
    RUN echo $'#!/bin/sh \n\ 
         export URL=example.com  \n\
         echo "${URL}" \n\
         node -e \'console.log("ENV URL value inside nodejs", process.env.URL)\' \n\
         exec "$@" \n\
         ' >> /bin/entrypoint.sh
    RUN chmod +x /bin/entrypoint.sh
    entrypoint ["entrypoint.sh"]
    
    

    So you when you Run docker container for the first time you will able to see the expected response.

    docker run -it --rm myapp
    example.com
    ENV URL value inside nodejs example.com
    

    Now we want to check for later session.

    docker run -it --rm abc  tail -f /dev/null
    example.com
    ENV URL value inside nodejs example.com
    

    so the container is up during this time, we can verify for another session

    docker exec -it myapp sh -c "node -e 'console.log(\"ENV URL value inside nodejs\", process.env.URL)'"
    ENV URL value inside nodejs undefined
    

    As we can same script but different behaviour because of docker, so the variable is only available in that session, you can write them to file if you are interested in later use.