Answers: <p>Please refer to bash initialization process.
  <a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html" rel="nofollow noreferrer">https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html</a></p>
  
  <p>In your <code>Dockerfile</code>, at lines 12-14 you are patching files, but do not activate any of rbenvs.
  Later at your last <code>RUN</code> call, you finally ARE activating an rbenv. This starts pointing at that specific version of ruby (I thin this patches <code>root</code> files)
  At that point you have different global shell initialization files vs. user initialization files.</p>
  
  <p>Difference</p>
  
  <ul>
  <li>entry point: "non-login" initialization process happens, then the file: <code>/root/.bashrc</code> is executed (a.k.a. "sourced"), it points to your cool ruby</li>
  <li><code>exec</code> of <code>ruby</code>: ruby executable is located using your default <code>PATH</code>. without running <code>/root/.bash*</code> files.</li>
  </ul>
  
  <p>To validate all this you can append printouts to your shell's initialization files, and see what gets printed upon 2 cases.</p>
  
  <p>Regards.</p>
  
Answers: CC BY-SA 4.0
Answers: 2018-08-10T08:34:03.593Z
Answers: Thanks for your answer! That makes sense, but is there a way I can force `docker exec` to source .bashrc without actually prepending `source ~/.bashrc && ` to every command I want to run? The reason this is an issue is that I have to start the container in detached mode, so I can only use exec to run commands. The only solution I've found so far is to force a symlink to /usr/bin/ruby `ln -nsf  ~/.rbenv/shims/ruby /usr/bin/ruby ` but that could break applications from ubuntu that rely on the system ruby version.
Answers: ConorSheehan1
Answers: CC BY-SA 4.0
Answers: 2018-08-12T15:29:11.240Z
Answers: @con-- I think you can create a wrapper script to do that for you, call it `/arbitrary_exec.sh` and do all the magic in it, executing everything as is at its bottom line: `"${@}"`, invoke by `exec /arbitrary_exec.sh mycmd bla bla bbla`
Answers: mvk_il
Answers: CC BY-SA 4.0
Answers: 2019-05-10T15:15:58.197Z
Answers: or you can put the bashrc in /etc/bashrc - or softlink or hardlink them
Answers: Dagelf
Answers: CC BY-SA 4.0
Answers: 2018-08-10T08:17:55.213Z
Answers: 2018-08-10T08:17:55.213Z
Answers: mvk_il
Answers: <p>I had a similar issue and was able to solve it as follows:<br />
  (Side-note: I had not much time to look deep into the topic, so I can not explain in detail why it works, but it worked)</p>
  <p>When executing <code>sudo docker -it exec container /bin/bash</code> I believe the shell gets started in interactive mode. This mode will source the .bashrc and so on (See link in answer from mvk_il).</p>
  <p>But with <code>sudo docker exec -it container /bin/bash -c '&lt;cmd&gt;'</code> the bash is executed in a different mode (I think even using &quot; or ' can make kind of a difference).</p>
  <p><strong>My solution:</strong><br />
  Execute the bash specificly in interactive mode and as a login shell. by that, it should behave the same way as if you enter the container and type the command by hand.<br />
  <code>sudo docker exec -it container /bin/bash -ilc '&lt;cmd&gt;'</code></p>
  
Answers: CC BY-SA 4.0
Answers: 2022-10-24T12:01:03.340Z
Answers: 2022-10-24T12:01:03.340Z
Answers: dohlenaugur
Body: <p>I have a docker image that looks something like this:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>My problem is that when I build the image and start a container</p>
  
  <pre><code>docker build -t test .
  docker run -it --name test-container test
  </code></pre>
  
  <p>If I run the commands directly in the container shell,<br>
  ruby is 2.4.1 (as I'd expect after running <code>rbenv global 2.4.1</code>)</p>
  
  <pre><code>ruby -v    # 2.4.1p111
  which ruby # /root/.rbenv/shims/ruby
  </code></pre>
  
  <p>But if I open a new shell and use docker exec,<br>
  ruby is 2.3.1, which is the system default</p>
  
  <pre><code>docker exec test-container ruby -v    # 2.3.1p112
  docker exec test-container which ruby # /usr/bin/ruby
  </code></pre>
  
  <hr>
  
  <p>I think it could have something to do with the bash profile not starting rbenv properly when using <code>docker exec</code>. The <code>env</code> command seems to have less output when using <code>docker exec</code> too, which is why I suspect something to do with .bashrc, .profile, or even /etc/profile not loading somehow.</p>
  
  <p>How can I ensure docker exec produces the same result as running the command directly on the container?</p>
  
Tags: <docker><bash>
Title: Docker exec environment different to container shell
UserDisplayName: ConorSheehan1
ThreadText: # Docker exec environment different to container shell
  
  (Asked by: username_0 on 2018-08-09)
  
  I have a docker image that looks something like this:
  
  ```
  FROM ubuntu:16.04
  
  # Install packages for building ruby
  RUN apt-get update && \
  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 && \
  git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build && \
  /root/.rbenv/plugins/ruby-build/install.sh && \
  echo 'eval "$(rbenv init -)"' >> /etc/profile
  echo 'eval "$(rbenv init -)"' >> ~/.profile && \
  echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  
  # Install ruby and bundler
  # Install Bundler
  ENV CONFIGURE_OPTS --disable-install-doc
  RUN rbenv install 2.4.1 && \
  echo 'gem: --no-rdoc --no-ri' >> ~/.gemrc && \
  rbenv global 2.4.1 && \
  rbenv local 2.4.1 && \
  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?
  
  **Tags:** docker, bash
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2018-08-10. Score: 2
  
  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.
  
  > **Comments:**
  > **username_0**: Thanks for your answer! That makes sense, but is there a way I can force `docker exec` to source .bashrc without actually prepending `source ~/.bashrc && ` to every command I want to run? The reason this is an issue is that I have to start the container in detached mode, so I can only use exec to run commands. The only solution I've found so far is to force a symlink to /usr/bin/ruby `ln -nsf  ~/.rbenv/shims/ruby /usr/bin/ruby ` but that could break applications from ubuntu that rely on the system ruby version.  
  > **username_1**: @con-- I think you can create a wrapper script to do that for you, call it `/arbitrary_exec.sh` and do all the magic in it, executing everything as is at its bottom line: `"${@}"`, invoke by `exec /arbitrary_exec.sh mycmd bla bla bbla`  
  > **username_2**: or you can put the bashrc in /etc/bashrc - or softlink or hardlink them  
  
  ---
  
  ### Answer by username_3 on 2022-10-24. Score: 0
  
  I had a similar issue and was able to solve it as follows:  
  (Side-note: I had not much time to look deep into the topic, so I can not explain in detail why it works, but it worked)
  
  When executing `sudo docker -it exec container /bin/bash` I believe the shell gets started in interactive mode. This mode will source the .bashrc and so on (See link in answer from mvk\_il).
  
  But with `sudo docker exec -it container /bin/bash -c '<cmd>'` the bash is executed in a different mode (I think even using " or ' can make kind of a difference).
  
  **My solution:**  
  Execute the bash specificly in interactive mode and as a login shell. by that, it should behave the same way as if you enter the container and type the command by hand.  
  `sudo docker exec -it container /bin/bash -ilc '<cmd>'`
  
  
  ---
  
  