Home > OS >  Why does echo of an environment variable do not work, but printenv does, inside a docker?
Why does echo of an environment variable do not work, but printenv does, inside a docker?

Time:05-05

My system: Visual studio code dev container, on Windows 10.

I try to use environment variables inside my docker container.

A file xyz.env holds my environment variables

TOKEN=12345

PROJECT_ID_1=8888
PROJECT_ID_2=9999

FOLDER=./tmp

I have a shell script script.sh

#!/bin/sh

BASEDIR=$(dirname $0)

docker run --rm \
    --env-file $BASEDIR/xyz.env \
    alpine:latest \
    printenv && echo "$HOSTNAME" && echo "$FOLDER" && echo "--- END ---"

When I call script.sh the output is

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=4ddcb55c018f
TOKEN=12345
PROJECT_ID_1=8888
PROJECT_ID_2=9999
FOLDER=./tmp
HOME=/root
072bf158678c

--- END ---

PATH, HOSTNAME, HOME is there already (I don't mind)

TOKEN, PROJECT_ID_1, PROJECT_ID_2 and FOLDER are there, when I print them via printenv.

  • When I use e.g. echo $FOLDER it is NOT there!? -> See empty line
  • When I use e.g. echo $HOSTNAME it is there, but with an different value!? -> See line before "end".

So how I can use the ENV variable from my file inside the docker container?

I have the same behavior when I run the docker run directly (without a script), like

docker run --rm \
    --env-file scripts/xyz.env \
    alpine:latest \
    printenv && echo "$HOSTNAME" && echo "$FOLDER" && echo "--- END ---"

CodePudding user response:

Simple, you are using variables from your host machine while running your command, as you are doing for $BASEDIR. As they don't exist on your host, your command looks like the following:

docker run --rm \
    --env-file scripts/xyz.env \
    alpine:latest \
    printenv && echo "" && echo "" && echo "--- END ---"

By escaping the dollar sign with \, the container should run the right command using its own env vars:

docker run --rm \
    --env-file $BASEDIR/xyz.env \
    alpine:latest \
    printenv && echo "\$HOSTNAME" && echo "\$FOLDER" && echo "--- END ---"

But this still won't work because of the &&: the container will run printenv, then your host will run the echo commands. You should run all of those as a single command:

docker run --rm \
    --env-file $BASEDIR/xyz.env \
    alpine:latest \
    /bin/sh -c 'printenv && echo "$HOSTNAME" && echo "$FOLDER" && echo "--- END ---"'

No need for escaping here as the commands are passed as a string with single quote, with no variable expansion from your host.

  • Related