Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduction of BUNDLE_APP_CONFIG leads to unexpected behavior for 'statically' bundled apps #129

Closed
MrMarvin opened this issue May 16, 2017 · 8 comments
Labels
question Usability question, not directly related to an error with the image

Comments

@MrMarvin
Copy link

In #69 the file based configuration for bundler was changed to a ENV based approach. This MR also adds a new configuration option for bundler: BUNDLE_APP_CONFIG, which changes how and where bundler looks for additional configuration. For example see https://github.com/docker-library/ruby/pull/69/files#diff-1578307c887a49e90a57418e653ad7f6R51

Bundlers default is:

Bundler retrieves its configuration from the local application (app/.bundle/config), environment variables, and the user's home directory (~/.bundle/config), in that order of priority.
(http://bundler.io/v1.3/man/bundle-config.1.html)

Which is imho a smart separation of project vs. global/user configuration, however in our docker based use case there really isn't a need for global bundler configuration.

With this setting set via Dockerfile ENV, we loose the ability to ship bundler configs with our apps. There are multiple ways of getting an app into the container, be it at buildtime or runtime (COPY'd, -ved or wget'ed during runtime ...) and not all necessarily include running bundle install at start up time! The main reason I noticed this behavior is because of one of my apps uses private gems that we bundle statically with bundle install --deployment. For those unfamiliar with the --deployment option, it basically does two things: 1. installs gems to a subdirectory of the project (commonly to vendor/bundle right besides the Gemfile) and 2. creates a .bundler/config file which changes the bundler path (per-project!) to the local directory the gems were just installed into.

Example of a FROM ruby:2.3 image:

root@e4477eb8fca6:/app# bundle list
Gems included by the bundle:
Could not find coderay-1.1.1 in any of the sources
root@e4477eb8fca6:/app# BUNDLE_APP_CONFIG=.bundle bundle list
Gems included by the bundle:
  * bundler (1.14.6)
  * coderay (1.1.1)
  * diff-lcs (1.3)
  * method_source (0.8.2)
  * mustermann (1.0.0)
  * pry (0.10.4)
  * puma (3.8.2)
  * rack (2.0.3)
  * rack-protection (2.0.0)
  * rack-test (0.6.3)
  * rspec (3.6.0)
  * rspec-core (3.6.0)
  * rspec-expectations (3.6.0)
  * rspec-mocks (3.6.0)
  * rspec-support (3.6.0)
  * sinatra (2.0.0)
  * slop (3.6.0)
  * tilt (2.0.7)

I am aware that one can easily change that behavior back to the default by changing the ENV when running the image, but I was wondering why we decided to change it in the first place? Pretty sure I am just missing something here and there is a good reason. cc @tianon

@johnpaulashenfelter
Copy link

I'll 👍 the question. Moving to the official ruby image killed our cron jobs unexpectedly since the BUNDLE_ environment variables aren't available to cron and both the global and bundle exec flavors of rake, in our example, can't find the installed rake gem.

I can solve it by dumping the env to a file and then sourcing it, but that's just... argh.

@perlun
Copy link
Contributor

perlun commented Aug 31, 2017

I agree, this also hit me know; I had to start debugging and looking into intermediate containers etc (our setup is a multi-container build, because we have a Ruby builder image and a node.js builder image, and then a minimal runtime image with FROM ruby:2.4-slim-stretch.

It's especially annoying since Docker does not allow me to delete an ENV variable, not that I know of. So know I have to hardwire it to .bundle/config in my Dockerfile, to then be able to copy it to the target image, or hardwire the copying from a really odd and unexpected location (/usr/local/bundle/config IIRC).

I am very much 👍 for removing BUNDLE_APP_CONFIG in the image; I did not expect it to be set to a random value.

@yosifkit
Copy link
Member

The BUNDLE_APP_CONFIG has been in the image since #21. This makes is possible to mount your local code directory to a container (or COPY it in) and not have a locally installed .bundle from your host interfere with the container (or have it overwritten when mounted).

@perlun
Copy link
Contributor

perlun commented Sep 1, 2017

The BUNDLE_APP_CONFIG has been in the image since #21. This makes is possible to mount your local code directory to a container (or COPY it in) and not have a locally installed .bundle from your host interfere with the container (or have it overwritten when mounted).

Valid points. It did cause me to waste a bit of time debugging an unexpected override of the bundler config, but your point makes sense. I can override it in my Dockerfile (first tried to set ti to the actual file location, but it must be the folder in which the .config file is located...)

Can we document this somewhere? Is it already documented perhaps? I think it's much easier for us to accept the way it is now, if it is clearly documented that it's done on purpose, for good and valid reasons.

@machisuke
Copy link

machisuke commented Nov 23, 2017

Do we have to explicitly declare BUNDLE_APP_CONFIG as /usr/local/bundle ?
According to official site, bundler automatically create ~/.bundle/config when you execute bundle config <name> <value>.
So, I think declaring the environment variable in Dockerfile only causes unexpected behavior for most people.

Actually, I also confused as unfamiliar variables were set automatically.

@kwerle
Copy link

kwerle commented Oct 23, 2019

This recently bit me. It's tempting to for the ruby docker images just to do one that does not set ENV vars.

@brandoncc
Copy link

This just got me too. Thanks to everyone in this thread, I'm back up and running :-)

@paddy-hack
Copy link

I've also been wondering about this. Although it doesn't appear to be doing me any harm(yet?), I don't seem to need it either. I run a

unset BUNDLE_APP_CONFIG

before starting my app to get rid of the variable. This works around the fact that you cannot remove the ENV var from the container image.

@machisuke Even though bundler uses ~/.bundle/config by default, relying on that assumes that $HOME is set to a writable location. I often run container via docker -u $UID:$GID. With the ruby image, that means I am an unknown user inside the container and $HOME is set to /.

For reference, I use something like the following to get a shell prompt when working on a Rails project

docker run --rm -it -v $PWD:/usr/src -w /usr/src -u $UID:$GID \
    -e HOME=/usr/src -e GEM_HOME=/usr/src/vendor/bundle \
    -e PATH=/usr/src/vendor/bundle:/usr/local/bin:/usr/bin:/bin \
    -p 3000:3000 ruby \
    bash -c 'unset BUNDLE_APP_CONFIG; exec bash'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Usability question, not directly related to an error with the image
Projects
None yet
Development

No branches or pull requests

9 participants