在Docker命令行上在容器内扩展环境变量

时间:2019-09-18 22:18:34

标签: bash docker

假设我创建了一个仅运行Dockerfile命令的echo

FROM alpine
ENTRYPOINT [ "echo" ]

我是这样构建的:

docker build -t my_echo .

如果我运行docker run --rm my_echo test,它将按预期输出test

但是如何运行命令以显示容器内 内的环境变量?

示例:

docker run --rm --env MYVAR=foo my_echo ???

如何通过替换???访问容器中的$MYVAR变量以显示foo。该命令的一部分?


注意: 这是我实际用例的简化版本。我真正的用例是使用Dockerfile构建的WP-CLI Docker映像。它具有wp-cli命令作为ENTRYPOINT。

我正在尝试基于该图像运行容器以使用环境变量更新WordPress参数。我没有Docker的命令是wp-cli option update siteurl "http://example.com",其中http://example.com将在环境变量中。

这是我要运行的命令( wp_cli 是我的容器的名称):

docker run --rm --env WEBSITE_URL="http://example.com" wp_cli option update siteurl ???

1 个答案:

答案 0 :(得分:1)

["bash", "-c"]之后紧跟其后的参数本身就是一个shell脚本,用于寻找替换的信号,这是可能的。例如,考虑以下脚本,我将其称为argEnvSubst

#!/usr/bin/env bash
args=( "$@" )                           # collect all arguments into a single array
for idx in "${!args[@]}"; do            # iterate over the indices of that array...
  arg=${args[$idx]}                     # ...and collect the associated values.
  if [[ $arg =~ ^@ENV[.](.*)@$ ]]; then # if we have a value that matches a pattern...
    varname=${BASH_REMATCH[1]}          # extract the variable name from that pattern
    args[$idx]=${!varname}              # and replace the value with a lookup result
  fi
done
exec "${args[@]}"                       # run our resulting array as a command.

因此,argEnvSubst "echo" "@ENV.foobar@"将在调用@ENV.foobar@之前将foobar替换为名为echo的环境的值。


虽然我强烈建议将其作为单独的脚本注入到Dockerfile中,并将该脚本命名为ENTRYPOINT,但可以直接在线进行:

ENTRYPOINT [ "bash", "-c", "args=(\"$@\"); for idx in \"${!args[@]}\"; do arg=${args[$idx]}; if [[ $arg =~ ^@ENV[.](.*)@$ ]]; then varname=${BASH_REMATCH[1]}; args[$idx]=${!varname}; fi; done; \"${args[@]}\"", "_" ]

...这样您就可以调用:

docker run --rm --env WEBSITE_URL="http://example.com" \
       wp_cli option update siteurl '@ENV.WEBSITE_URL@'

请注意使用bash -这意味着alpine(仅提供破折号)是不够的。