Dockerfile RUN 中的环境和正在运行的容器上的交互式 shell 之间的区别



我从一个安装了OracleXE的Docker镜像开始。 此映像有一个正在运行的实例,其中配置了所有内容。
我可以启动该图像,并且,无论是从交互式shell容器,还是通过ssh'ing到容器中,我都可以轻松执行sqlplus

要创建一个包含我想要添加的容器,例如新的预言机用户和表空间,我可以进入正在运行的容器并执行必要的sqlplus,然后docker commit具有新状态的新映像。 但是,我想在Dockerfile中捕捉这些新变化。

但是......当我的Dockerfile尝试执行上面提到的相同命令时,PATH没有ORACLE_HOME;而当我使用SSH或交互式shell进入容器时,它显然是这样做的。

请注意,上面链接的原始 Dockerfile 使用以下方法来设置 PATH。

RUN echo 'export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe' >> /etc/bash.bashrc
RUN echo 'export PATH=$ORACLE_HOME/bin:$PATH' >> /etc/bash.bashrc
RUN echo 'export ORACLE_SID=XE' >> /etc/bash.bashrc

执行 RUN 命令时的环境与通过交互式 shell 或 SSH 进入容器时的环境有什么区别? 请注意,这一切都始于 ubuntu 14.04 映像。

请参阅启动文件上的 Bash 手动条目。

当你以交互方式运行时,shell 会执行其 rcfiles:

当 Bash 作为交互式登录 shell 调用或使用 --login 选项作为非交互式 shell 调用时,它首先从文件/etc/profile 中读取并执行命令(如果该文件存在)。读取该文件后,它会按该顺序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,并从存在且可读的第一个命令中读取和执行命令。

当你的 Dockerfile 正在构建时,它运行的是一个非交互式 shell:

例如,当 Bash 以非交互方式启动时,为了运行 shell 脚本,它会在环境中查找变量BASH_ENV,如果它出现在那里,则展开其值,并使用扩展的值作为要读取和执行的文件的名称。

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi`

您可以设置BASH_ENV以使事情运行。或者在 Dockerfile 的每一行上使用 RUN bash --login <command>RUN . /etc/bash.bashrc && <command>。不过,这很恶心。

我会使用 ENV dockerfile 命令来设置这些变量。我不确定为什么原版会以这种方式设置它们。

最新更新