Dockerfile 运行 中的环境与 运行 容器中的交互式 shell 之间的区别?

Difference between environment in Dockerfile RUN and interactive shell on a running container?

我从 Docker image that has OracleXE installed on it 开始。此图像有一个 运行 实例,所有配置都已配置。
我可以启动那个图像,并且,无论是从交互式 shell 容器,还是通过 ssh 进入容器,我都可以轻松地执行 sqlplus

要创建一个包含我想要添加的内容的容器,例如新的 oracle 用户和表空间,我可以进入 运行 容器并执行必要的 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

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

参见Bash manual entry on startup files

当您 运行 交互时,shell 执行它的 rcfiles:

When Bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

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

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.

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

可以设置BASH_ENV来制作东西运行。或者在 Dockerfile 的每一行上使用 RUN bash --login <command>RUN . /etc/bash.bashrc && <command>。不过,这太恶心了。

我会使用 ENV dockerfile 命令来设置这些变量。我不确定为什么原来的设置是这样的。