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:
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:
- gem installation directory, which is configured in bundler's configuration that is packed with the image
BUNDLE_APP_CONFIG
environment variable defined in the docker image
looking at bundler documentation, we have to note few things:
- list of available keys,
BUNDLE_PATH
is not there, butpath
is...
The location to install the specified gems to.
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
. IfBUNDLE_APP_CONFIG
is set, the configuration will be stored in$BUNDLE_APP_CONFIG/config
- 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:
- bundler's configuration is stored in your local directory
- bundler installed the gems into your local directory