首页 > 解决方案 > 通过 .env 文件的命令扩展为 `docker run` 生成参数

问题描述

docker run在以相对通用的方式传递一些环境参数时遇到了一些问题。

我们的第一次迭代是.env通过以下几行将文件加载到环境中:

set -o allexport;
. "${PROJECT_DIR}/.env";
set +o allexport;

然后手动键入命令的--env VARNAME=$VARNAMEas 选项docker run。但是当你有几十个变量时,这可能会很烦人。

然后我们尝试使用 , 传递文件,--env-file .env似乎可以工作,但它没有,因为它不能很好地与变量值周围的引号一起使用。

这是我开始做疯狂/丑陋的事情的地方。基本的想法是做类似的事情:

set_docker_parameters()
{
    grep -v '^$' "${PROJECT_DIR}/.env" | while IFS= read -r LINE; do
        printf " -e %s" "${LINE}"
    done
}

docker run $(set_docker_parameters) --rm image:label command

已解析的行类似于VARIABLE="value",VARIABLE='value'VARIABLE=value. 空行被管道丢弃grep

但是docker run一直抱怨没有被正确调用。当我扩展结果时,set_docker_parameters我得到了我的预期,当我复制它的结果并替换$(set_docker_parameters)时,docker run也可以按预期工作,完美无缺。

知道我在这里做错了什么吗?

非常感谢!

PS:我正在尝试使我的脚本 100% 与 POSIX 兼容,因此我更喜欢任何不依赖 Bash 特定功能的解决方案。

标签: bashshelldockershposix

解决方案


根据@jordanm 的评论,我设计了以下解决方案:

docker_run_wrapper()
{
    # That's not ideal, but in any case it's not directly related to the question.
    cmd=$1

    set --; # Unset all positional arguments ($@ will be emptied)

    # We don't have arrays (we want to be POSIX compatible), so we'll
    # use $@ as a sort of substitute, appending new values to it.
    grep -v '^$' "${PROJECT_DIR}/.env" | while IFS= read -r LINE; do
        set -- "$@" "--env";
        set -- "$@" "${LINE}";
    done

    # We use $@ in a clearly non-standard way, just to expand the values
    # coming from the .env file.
    docker run "$@" "image:label" /bin/sh -c "${cmd}";
}

再说一次,这不是我为特定用例编写的代码,而是显示基本思想的简化。如果你可以依赖 Bash,那么它可能会更干净,因为它不会重载$@和使用数组。


推荐阅读