Reputation: 34155
Here is my docker file which works:
FROM ruby:2.6.6
WORKDIR /home/app/webapp
COPY . /home/app/webapp/
RUN bundle install
# Start the main process.
CMD ['/home/app/webapp/entrypoint.sh']
this works fine but it does bundle install every-time! Instead, I have all gems vendors in /vendor/cache directly in the git source itself.
$ ls vendor/cache
<..snip long list.>
rake-13.0.1.gem
rails-5.2.4.1.gem
rails-controller-testing-1.0.4.gem
rails-dom-testing-2.0.3.gem
rails-html-sanitizer-1.3.0.gem
rails-i18n-5.1.3.gem
rails-ujs-0.1.0.gem
sass-rails-5.0.8.gem
sprockets-rails-3.2.1.gem
<..snip long list.>
as per the bundler docs: https://bundler.io/bundle_install.html, this should work as it says:
While installing gems, Bundler will check vendor/cache and then your system's gems. If a gem isn't cached or installed, Bundler will try to install it from the sources you have declared in your Gemfile.
this indeed works when I bundle on my mac without docker as shown below:
$ bundle
Using rake 13.0.1
Using rails 5.2.4.1
Using rails-controller-testing 1.0.4
Using rails-i18n 5.1.3
Using rails-ujs 0.1.0
Using sidekiq-pro 4.0.4
Updating files in vendor/cache
Bundle complete! 144 Gemfile dependencies, 304 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Hence, I modify my the dockerfile to take advantage of caching. so I do bundle install only once and save it as a layer. Then, for any code changes, it doesn't need bundle install again
FROM ruby:2.6.6
WORKDIR /home/app/webapp
COPY Gemfile Gemfile.lock /vendor/cache/ /home/app/webapp/
RUN bundle install
COPY . /home/app/webapp/
# Start the main process.
CMD ['/home/app/webapp/entrypoint.sh']
now, when I try to build this, I got the following error:
$ docker-compose build
redis uses an image, skipping
db uses an image, skipping
Building rails
Step 1/6 : FROM ruby:2.6.6
---> 107c48f680c0
Step 2/6 : WORKDIR /home/app/webapp
---> Using cache
---> f23fc51ac8ba
Step 3/6 : COPY Gemfile Gemfile.lock /vendor/cache/ /home/app/webapp/
---> 0d1f451b7ee0
Step 4/6 : RUN bundle install
---> Running in 5768798c1bcd
Warning: the running version of Bundler (1.17.2) is older than the version that created the lockfile (1.17.3). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
Fetching gem metadata from https://rubygems.org/.......
Could not find sidekiq-pro-4.0.4 in any of the sources
ERROR: Service 'rails' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 7
However, the sidekiq-pro gem is already in the vendor/cache
$ ls vendor/cache | grep sidekiq-pro
sidekiq-pro-4.0.4.gem
so this does work on local mac without docker as bundler picks up the sidekiq gem from cache but it doesn't work with docker. Any idea on what else I can try?
Upvotes: 4
Views: 3651
Reputation: 34155
I managed to solve this. needed to edit the Dockerfile to copy gems at vendor/cache. Here is the modified gemfile which works and utilized docker caching
FROM ruby:2.6.6
WORKDIR /home/app/webapp
COPY Gemfile Gemfile.lock /home/app/webapp/
COPY vendor/cache /home/app/webapp/vendor/cache/
RUN bundle install
COPY . /home/app/webapp/
# Start the main process.
CMD ['/home/app/webapp/entrypoint.sh']
Adding the answer here, incase someone else get's the same error. Thank you for looking.
Upvotes: 6