【问题标题】:Setting environment variables when running docker in detached mode在分离模式下运行 docker 时设置环境变量
【发布时间】:2020-11-11 15:07:20
【问题描述】:

如果我在 /root/.bashrc 中包含以下行:

export $A = "AAA"

然后,当我在交互模式下运行 docker 容器 (docker run -i) 时,$A 变量会保持其值。但是,如果我以分离模式运行容器,我将无法访问该变量。即使我运行容器明确采购 .bashrc 之类的

docker run -d my_image /bin/bash -c "cd /root && source .bashrc && echo $A"

这样的行产生一个空输出。

那么,为什么会这样呢?以及如何设置.bashrc文件中定义的环境变量?

任何帮助将不胜感激!

【问题讨论】:

    标签: bash shell docker


    【解决方案1】:

    第一个问题是您正在运行的命令有 $A 被您的主机外壳(而不是容器外壳)解释。在您的主机上,$A 可能是黑色的,因此您的有效命令变为:

    docker run -i my_image /bin/bash -c "cd /root && source .bashrc && echo "
    

    正如它所说的那样。我们可以对变量进行转义,以便将其发送到容器并在那里正确评估:

    docker run -i my_image /bin/bash -c "echo \$A"
    

    但这也将是空白的,因为虽然容器是,但外壳不是处于交互模式。但我们可以强制它是:

    docker run -i my_image /bin/bash -i -c "echo \$A"
    

    哇哦,我们终于得到了我们想要的结果。但是由于没有 TTY,因此 bash 增加了一个错误。因此,我们可以设置一个伪 TTY,而不是交互模式:

    docker run -t my_image /bin/bash -i -c "echo \$A"
    

    【讨论】:

    • 太棒了!只是一个问题,最后两个代码sn-ps是一样的。设置伪 TTY 的代码是什么?非常感谢!
    • 抱歉,我将其修改为 -t(伪 TTY)而不是 -i。但它也可能是-it(伪 TTY 和交互式)。我试图说明的一点是交互式控制台不是由 bash 本身继承的,仍然必须在 bash 上设置。
    • 抱歉,问题标题明确询问了“分离模式”,而您的回答恰恰相反。有人找到了分离模式的方法吗?
    【解决方案2】:

    运行一些测试后,似乎在分离模式下运行容器时,覆盖默认环境变量并不总是以我们想要的方式发生,具体取决于您在 Dockerfile 中的位置。

    例如,如果在分离的容器中运行容器,如下所示:

    docker run **-d** --name image_name_container image_name
    

    您在 Dockerfile 定义的任何 ENV 变量都会在任何地方生效(阅读其余部分,您将了解 everywhere 的含义)。

    一个简单的 dockerfile 示例(alpine 只是一个轻量级的 linux 发行版):

    FROM alpine:latest
    
    #declaring a docker env variable and giving it a default value
    ENV MY_ENV_VARIABLE dummy_value
    
    #copying two dummy scripts into a place where i can execute them straight away
    COPY ./start.sh /usr/sbin
    COPY ./not_start.sh /usr/sbin
    
    #in this script i could do: echo $MY_ENV_VARIABLE > /test1.txt
    RUN not_start.sh
    RUN echo $MY_ENV_VARIABLE > /test2.txt
    
    #in this script i could do: echo $MY_ENV_VARIABLE > /test3.txt
    ENTRYPOINT ["start.sh"]
    

    现在,如果您想在 detached 中运行容器并覆盖一些 ENV 变量,如下所示:

    docker run **-d** -e MY_ENV_VARIABLE=new_value --name image_name_container image_name
    

    惊喜! var MY_ENV_VARIABLE 仅在 ENTRYPOINT 中运行的脚本中被覆盖(我检查过,如果您将 ENTRYPOINT 替换为 CMD,也会发生同样的事情)。它也将被覆盖在您可以从此 start.sh 脚本调用的下标中。但是在 RUN dockerfile 命令或 dockerfile 本身中调用的 MY_EV_VARIABLE 变量不会被覆盖。

    换句话说,我们会将 $MY_ENV_VARIABLE 替换为值 dummy_valuenew_value 取决于您是否在ENTRYPOINT 中。

    【讨论】:

    猜你喜欢
    • 2020-10-22
    • 1970-01-01
    • 2020-01-12
    • 2017-05-11
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多