paketo-buildpacks / bundle-install

A Cloud Native Buildpack to install gems from a Gemfile
Apache License 2.0
7 stars 6 forks source link

Bundle install reuses layer even when bundle-respected env vars should change app image setup #111

Open fg-j opened 3 years ago

fg-j commented 3 years ago

What happened?

Please provide some details about the task you are trying to accomplish and what went wrong. We were trying to use some build-time configuration that the bundle tool natively respects to change the contents of the built app image. In particular, we wanted to take advantage of the BUNDLE_WITHOUT environment variable to exclude certain gems from the built app image. Rather than rebuilding the gems layer, the buildpack reused the cached version of the layer. The resulting app image included gems we didn't want in our image.

Reproduction steps

  1. Clone this sample app
  2. Change the Gemfile to contain:
    
    source 'https://rubygems.org'

ruby '~> 2.0'

group :test do gem 'rspec' end

gem 'puma' gem 'sinatra'

3. Run `bundle` locally to generate a `Gemfile.lock`. 
4. Build the app with all of its gems:
```shell
pack build exclude-gems  --builder paketobuildpacks/builder:0.1.20-base --buildpack gcr.io/paketo-buildpacks/ruby:0.1.5 --clear-cache
  1. Hop into the built app and see that the rspec gem is present:
    docker run -it --entrypoint=launcher exclude-gems /bin/bash
    cnb@fa0d8cb9967f:/workspace$ ls /layers/paketo-buildpacks_bundle-install/gems/ruby/2.7.0/gems/
    diff-lcs-1.4.4    nio4r-2.5.4  rack-2.2.3             rspec-3.10.0       rspec-expectations-3.10.0  rspec-support-3.10.0  sinatra-2.1.0
    mustermann-1.1.1  puma-5.0.4   rack-protection-2.1.0  rspec-core-3.10.0  rspec-mocks-3.10.0         ruby2_keywords-0.0.2  tilt-2.0.10
  2. Rebuild the app with the BUNDLE_WITHOUT env var to exclude the test group:
    pack build exclude-gems  --builder paketobuildpacks/builder:0.1.20-base --buildpack gcr.io/paketo-buildpacks/ruby:0.1.5 --env BUNDLE_WITHOUT=test

    The output should contain:

    [builder] Paketo Bundle Install Buildpack 0.1.0
    [builder]   Reusing cached layer /layers/paketo-buildpacks_bundle-install/gems
    [builder]
  3. Hop into the app container again and see that rspec is still present in the app container
    docker run -it --entrypoint=launcher exclude-gems /bin/bash
    cnb@546bd3d68aea:/workspace$ ls /layers/paketo-buildpacks_bundle-install/gems/ruby/2.7.0/gems/
    diff-lcs-1.4.4    nio4r-2.5.4  rack-2.2.3             rspec-3.10.0       rspec-expectations-3.10.0  rspec-support-3.10.0  sinatra-2.1.0
    mustermann-1.1.1  puma-5.0.4   rack-protection-2.1.0  rspec-core-3.10.0  rspec-mocks-3.10.0         ruby2_keywords-0.0.2  tilt-2.0.10

The buildpack should rebuild the gems layer in a way that respects this native configuration. Notably, running

pack build exclude-gems  --builder paketobuildpacks/builder:0.1.20-base --buildpack gcr.io/paketo-buildpacks/ruby:0.1.5 --env BUNDLE_WITHOUT=test --clear-cache

produces the desired result, where rspec gems are not present.

Checklist

Please confirm the following:

fg-j commented 2 years ago

@paketo-buildpacks/ruby-maintainers This issue has been open for a while. Does this need to be investigated further before it's workable?

@richardTowers Is this still a problem for you?

sophiewigmore commented 2 years ago

@fg-j while this specific example doesn't fully apply anymore (because the buildpack runs with bundle-without already now), the case in which the environment variables aren't taken into account still stands. I don't think further investigation is necessary.