Home > Enterprise >  Using a Docker image to run bundle install ignores bundle config setting
Using a Docker image to run bundle install ignores bundle config setting

Time:12-18

I'm hoping to use a Docker image (ruby:3.0) build an image without (eventually) having to have Ruby installed locally.

For testing purposes, I have Ruby 2.7.0 installed in Windows 10 WSL2 environment:

$ ruby -v
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux-gnu]

I have a Gemfile:

source 'https://rubygems.org'

gem 'sinatra'

group :development, :test do
    gem 'thin'
    gem 'sqlite3'
end

And bundler set to install Gems in the project's directory:

$ cat .bundle/config
---
BUNDLE_PATH: "vendor/bundle"

If I run bundle install locally:

$ bundle install
Fetching gem metadata from https://rubygems.org/...
Resolving dependencies...
Using bundler 2.2.17
Fetching rack 2.2.3
Fetching tilt 2.0.10
Fetching daemons 1.4.1
Fetching sqlite3 1.4.2
Fetching eventmachine 1.2.7
Fetching ruby2_keywords 0.0.5
Installing rack 2.2.3
Installing tilt 2.0.10
Installing sqlite3 1.4.2 with native extensions
Installing ruby2_keywords 0.0.5
Installing daemons 1.4.1
Installing eventmachine 1.2.7 with native extensions
Fetching mustermann 1.1.1
Installing mustermann 1.1.1
Fetching rack-protection 2.1.0
Installing rack-protection 2.1.0
Fetching sinatra 2.1.0
Installing sinatra 2.1.0
Fetching thin 1.8.1
Installing thin 1.8.1 with native extensions
Bundle complete! 3 Gemfile dependencies, 11 gems now installed.
Bundled gems are installed into `./vendor/bundle`

the Gems are installed to the ./vendor/bundle directory:

enter image description here

confirmed:

$ bundle info thin
  * thin (1.8.1)
        Summary: A thin and fast web server
        Homepage: https://github.com/macournoyer/thin
        Source Code: https://github.com/macournoyer/thin
        Changelog: https://github.com/macournoyer/thin/blob/master/CHANGELOG
        Path: /home/craig/ruby/dev/vendor/bundle/ruby/2.7.0/gems/thin-1.8.1

Next, I use the ruby:3.0 image to bundle the Gems in the project's directory.

I removed the Gemfile.lock and ./vendor/bundle directory, then ran bundle install using the image:

$ docker run --rm -v "$(pwd)":/src -w /src ruby:3.0 bundle install
Fetching gem metadata from https://rubygems.org/...
Resolving dependencies...
Using bundler 2.2.32
Fetching sqlite3 1.4.2
Fetching eventmachine 1.2.7
Fetching rack 2.2.3
Fetching tilt 2.0.10
Fetching ruby2_keywords 0.0.5
Fetching daemons 1.4.1
Installing ruby2_keywords 0.0.5
Installing tilt 2.0.10
Installing daemons 1.4.1
Installing sqlite3 1.4.2 with native extensions
Installing rack 2.2.3
Fetching mustermann 1.1.1
Installing eventmachine 1.2.7 with native extensions
Installing mustermann 1.1.1
Fetching rack-protection 2.1.0
Installing rack-protection 2.1.0
Fetching sinatra 2.1.0
Installing sinatra 2.1.0
Fetching thin 1.8.1
Installing thin 1.8.1 with native extensions
Bundle complete! 3 Gemfile dependencies, 11 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

This process seemed to install the Gems, but not to ./vendor/bundle. Trying to identify the location generates an error:

$ bundle info thin
Could not find daemons-1.4.1 in any of the sources

It would appear that .bundle/config is being ignored. I'm guessing that the Gems are actually being installed into the container that is created to run bundle install.

Is there a way to get this to use .bundle/config?

CodePudding user response:

this happens due to few things:

  1. gem installation directory, which is configured in bundler's configuration that is packed with the image
  2. BUNDLE_APP_CONFIG environment variable defined in the docker image

looking at bundler documentation, we have to note few things:

  1. list of available keys, BUNDLE_PATH is not there, but path is...

The location to install the specified gems to.

  1. executing config

Executing bundle config set --local <name> <value> will set that configuration in the directory for the local application. The configuration will be stored in <project_root>/.bundle/config. If BUNDLE_APP_CONFIG is set, the configuration will be stored in $BUNDLE_APP_CONFIG/config

  1. Bundler loads configuration settings in this order

Local config (<project_root>/.bundle/config ...)

let's give it try...

$ docker run --rm -it -v $PWD:/src --workdir /src --entrypoint /bin/sh ruby:alpine

/src # ls -l
total 0

/src # echo $BUNDLE_APP_CONFIG
/usr/local/bundle

/src # export BUNDLE_APP_CONFIG=$PWD/.bundler

$ bundle config set --local path 'vendor/bundle'
/src # ls -la
total 4
drwxr-xr-x    3 root     root            96 Dec 16 21:10 .
drwxr-xr-x    1 root     root          4096 Dec 16 21:10 ..
drwxr-xr-x    3 root     root            96 Dec 16 21:10 .bundler

/src # bundle config
Settings are listed in order of priority. The top value will be used.
app_config
Set via BUNDLE_APP_CONFIG: "/src/.bundler"

path
Set for your local app (/src/.bundler/config): "vendor/bundle"

silence_root_warning
Set via BUNDLE_SILENCE_ROOT_WARNING: true

/src # bundle init
Writing new Gemfile to /src/Gemfile

/src # echo 'gem "sinatra"' >> Gemfile

/src # bundle install --quiet

/src # ls -l
total 8
-rw-r--r--    1 root     root           161 Dec 16 21:12 Gemfile
-rw-r--r--    1 root     root           398 Dec 16 21:13 Gemfile.lock
drwxr-xr-x    3 root     root            96 Dec 16 21:18 vendor

/src # du -sh vendor/bundle/
3.1M    vendor/bundle/

/src # bundle exec rackup --version
Rack 1.3 (Release: 2.2.3)

/src # exit

$ ls -ax1
.
..
.bundler
Gemfile
Gemfile.lock
vendor

as you can see:

  1. bundler's configuration is stored in your local directory
  2. bundler installed the gems into your local directory
  • Related