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.