【问题标题】:Updating PATH environment variable permanently in Docker container在 Docker 容器中永久更新 PATH 环境变量
【发布时间】:2015-04-27 15:43:23
【问题描述】:

我尝试在文件~/.profile/etc/profile 中添加PATH,如下所示。

PATH = $PATH:/required/path

但是,它不起作用。然后我尝试添加行显示,这也不起作用。

export PATH

即使重新启动容器和主机后它也不起作用。

【问题讨论】:

  • 问题是在创建容器并进行了一些修改之后。不是在使用 Docker 配置文件创建容器时。

标签: environment-variables docker linux-containers


【解决方案1】:

没有说明交互式和非交互式 shell 之间的区别。因此,这就是为什么上述解决方案有时似乎有效,有时无效的原因。

bashrc 文件通常会被非交互式 shell 跳过。例如在 Debian 中,/etc/bash.bashrc 文件非常清楚地指出:

# System-wide .bashrc file for interactive bash(1) shells.

# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.

# If not running interactively, don't do anything
[ -z "$PS1" ] && return
  • Dockerfile 中的RUN 命令调用非交互式 shell。并且ENV设置的路径会被占用,bashrc脚本不会运行。
  • docker run -it <image> /bin/bash 调用 交互式 shell。 bashrc 将运行并且可以覆盖在ENV 中设置的任何内容,例如,如果PATH 没有在任何bashrc 脚本中的常用PATH=$PATH:/... 语法中定义。

为了两种操作模式之间的安全和一致,可以在 Dockerfile 中进行:

ENV PATH /master/go/bin:${PATH}
RUN echo "${PATH}" >> /etc/bash.bashrc

请注意,/etc/bash.bashrc 是 Debian 位置,可能与其他发行版映像不同。

【讨论】:

    【解决方案2】:

    这是我的 docker 文件,在 Centos 上我已经提取并设置了 java 主路径,它对我有用。

    Dockerfile:

    FROM  centos:7
    RUN yum update -y yum install -y tar
    COPY jdk-7u80-linux-x64.tar.gz /opt/
    WORKDIR /opt
    RUN tar -xvf jdk-7u80-linux-x64.tar.gz
    RUN chmod -R 755 jdk1.7.0_80
    RUN echo export JAVA_HOME=/opt/jdk1.7.0_80 >> /etc/profile
    RUN echo export PATH='$PATH:$JAVA_HOME/bin' >> /etc/profile
    ENV JAVA_HOME "/opt/jdk1.7.0_80"
    ENV PATH "${JAVA_HOME}/bin:${PATH}"
    

    【讨论】:

      【解决方案3】:

      1。正确答案

      最佳投票答案建议将ENV PATH "$PATH:/new/path" 添加到 Dockerfile,这确实应该有效。

      2。那么为什么它对我不起作用?

      正如某些 cmets/answers 中所述,解决方案 1. 对某些人不起作用。

      原因是PATH可以在运行docker容器时被.bashrc之类的脚本覆盖,从而给人的印象是ENV PATH...不起作用,但理论上是可以的。

      要解决此问题,您需要通过将以下命令添加到 Dockerfile 来将正确的 PATH 附加到 .bashrc

      RUN echo "export PATH=/new/path:${PATH}" >> /root/.bashrc

      【讨论】:

      • 好的,但是如何重新加载环境以便 bash 看到更改?
      【解决方案4】:

      如果您想在 Dockerfile 中包含 /new/path,请添加以下行:

      ENV PATH "$PATH:/new/path"

      Dockerfile 中应该可以工作。

      【讨论】:

      • 注意引号很重要。
      • 这适用,但不适用于所有用户。知道如何让所有人都可以使用它吗?
      • 使用 ENV 是不可能的,相反你必须使用类似于 /etc/environment 的东西:github.com/moby/moby/issues/15383
      • 这对我来说很好。我需要将 JDK 添加到映像中(我不能只使用 apt install,必须单独下载和提取),所以我添加了 ENV JAVA_HOME "/path/to/jdk" 和 ENV PATH "${JAVA_HOME}/垃圾箱:${PATH}”。重建映像后,构建用户可以使用 JDK。
      • 在 IBM 的 LSF 中是否有特殊的方法可以做到这一点?
      【解决方案5】:

      我在 irc 聊天中得到了这个问题的答案。在这里给出是为了任何可能遇到此问题的人的利益。许多人在更新~/.profile 时给出了错误的答案,但这并没有奏效。所以请使用下面的答案。

      为用户更新文件~/.bashrc 或更新文件/etc/enviroment global 以进行适用于所有用户的全局更改。

      .bashrc 导出路径:export PATH=$PATH:/new/path/bin

      在环境中:PATH=$PATH:/new/path/bin

      【讨论】:

      • 考虑到这个问题与 Docker 有关,我认为 Jason Gao 的回答应该是公认的。更新 bash 配置文件是在标准非容器化环境中存储变量的好方法,但如果您在容器中部署,则在 Dockerfile 中包含 ENV 步骤更简洁。
      • 根据这个 Ubuntu 文档,'in environment' 的方法是不正确的(注意:变量扩展在 /etc/environment 中不起作用。)。 help.ubuntu.com/community/…
      • 所以设置 .bashrc 文件似乎只在作为交互式终端运行时才有效,因为它将运行用户的默认 shell。除非您通过 bash 发送命令,否则使用该文件将无法在容器内运行命令。
      • 有人请修改这个。我刚刚浪费了 1 个小时来思考为什么它不会扩展。 ty @dangeroushobo
      【解决方案6】:

      在您的 Dockerfile 中添加一行 ENV PATH xxx 参见此 Dockerfile 中的示例 https://gist.github.com/deepak/5933685

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 2014-04-23
        • 1970-01-01
        • 2012-08-09
        • 2011-08-15
        • 2016-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多