Docker exec environment different to container shell I have a docker image that looks something like this:

FROM ubuntu:16.04

# Install packages for building ruby
RUN apt-get update &amp;&amp; \
apt-get -y install build-essential git curl wget net-tools apt-utils sudo man \
libssl-dev libreadline-dev libyaml-dev nano gcc rubygems ruby-dev

# Install rbenv and ruby-build
ENV PATH /root/.rbenv/bin:$PATH
RUN git clone https://github.com/sstephenson/rbenv.git /root/.rbenv &amp;&amp; \
git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build &amp;&amp; \
/root/.rbenv/plugins/ruby-build/install.sh &amp;&amp; \
echo 'eval "$(rbenv init -)"' &gt;&gt; /etc/profile
echo 'eval "$(rbenv init -)"' &gt;&gt; ~/.profile &amp;&amp; \
echo 'eval "$(rbenv init -)"' &gt;&gt; ~/.bashrc

# Install ruby and bundler
# Install Bundler
ENV CONFIGURE_OPTS --disable-install-doc
RUN rbenv install 2.4.1 &amp;&amp; \
echo 'gem: --no-rdoc --no-ri' &gt;&gt; ~/.gemrc &amp;&amp; \
rbenv global 2.4.1 &amp;&amp; \
rbenv local 2.4.1 &amp;&amp; \
gem install bundler

ENTRYPOINT /bin/bash


My problem is that when I build the image and start a container

docker build -t test .
docker run -it --name test-container test


If I run the commands directly in the container shell,
ruby is 2.4.1 (as I'd expect after running rbenv global 2.4.1)

ruby -v    # 2.4.1p111
which ruby # /root/.rbenv/shims/ruby


But if I open a new shell and use docker exec,
ruby is 2.3.1, which is the system default

docker exec test-container ruby -v    # 2.3.1p112
docker exec test-container which ruby # /usr/bin/ruby




I think it could have something to do with the bash profile not starting rbenv properly when using docker exec. The env command seems to have less output when using docker exec too, which is why I suspect something to do with .bashrc, .profile, or even /etc/profile not loading somehow.

How can I ensure docker exec produces the same result as running the command directly on the container?
Please refer to bash initialization process.
https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html

In your Dockerfile, at lines 12-14 you are patching files, but do not activate any of rbenvs.
Later at your last RUN call, you finally ARE activating an rbenv. This starts pointing at that specific version of ruby (I thin this patches root files)
At that point you have different global shell initialization files vs. user initialization files.

Difference


entry point: "non-login" initialization process happens, then the file: /root/.bashrc is executed (a.k.a. "sourced"), it points to your cool ruby
exec of ruby: ruby executable is located using your default PATH. without running /root/.bash* files.


To validate all this you can append printouts to your shell's initialization files, and see what gets printed upon 2 cases.

Regards.