Skip to content
Advertisement

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

I’m starting with a Docker image that has OracleXE installed on it. This image has a running instance, with everything configured.
I can fire up that image, and, either from an interactive shell container, or by ssh’ing into the container, I can easily execute sqlplus.

To create a container with my desire additions, such as a new oracle user and tablespaces, I can go into the running container and execute the necessary sqlplus, and then docker commit a new image with my new state. However, I would like to capture these new changes in a Dockerfile.

BUT . .. when my Dockerfile tries to execute the same commands as referenced above, the PATH doesn’t have the ORACLE_HOME on it; while it clearly does when I go into the container with SSH or interactive shell.

Note, the original Dockerfile, linked to above, uses the following to set the 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

What’s the difference between the environment when the RUN command executes and when I go into the container via the interactive shell or SSH? Note, this all starts with a ubuntu 14.04 image.

Advertisement

Answer

See the Bash manual entry on startup files.

When you run interactively, the shell executes its 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.

When your Dockerfile is building, it’s running a non-interactive 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`

You could set BASH_ENV to make things run. Or use RUN bash --login <command> or RUN . /etc/bash.bashrc && <command> on every line of your Dockerfile. That’s pretty gross, though.

I would use the ENV dockerfile command to set those variables. I’m not sure why the original set them up the way it does.

Advertisement