Everyday I'm bundling
| ruby docker unix devopsI decided to try a slightly different approach with bundler for
production, trying my hand at packing the projects gems to
vendor/cache
. I used this
article
as a reference point. It’s a bit old, but still applicable.
Using bundle package
to package gems into vendor/cache
trades
repository file space for quicker bundling. I did run into a couple
issues with trying to handle platform-specific gems like
google-protobuf
. I found other folks were have similar
issues.
I generally develop without using Docker, so this was an opportunity to
learn about this conundrum. Docker for macOS uses the x86_64-linux
platform, so when Docker failed to bundle successfully, I saw that
my gem sources was missing the google-protobuf
gem. Looking further
into it, I had to enable a couple options for bundle config
:
BUNDLE_CACHE_ALL: "true"
BUNDLE_CACHE_ALL_PLATFORMS: "true"
BUNDLE_SPECIFIC_PLATFORM: "true"
These flags ensure that vendor/cache
contained all the necessary
gems. I had to add the x86_64-linux
platform Gemfile.lock
to ensure
bundle package
would pick it up. Bundler’s bundle config
docs
lists all available flags and provides description. Running bundle
install
with the deployment flag installs gems to vendor/bundle
instead of the default system location (though I don’t know how much
this matters with Docker, since each container is self-contained HAHA).
The local flag is interesting since bundler will install gems directly
using vendor/cache
as the gem source, avoiding gem downloads from
RubyGems, GitHub, etc…
I ended up with the following production Dockerfile. The last step is
overridden with kubernetes. Builds are super fast, I’ve never been this
excited about our CI/CD pipeline! The image takes ~4 minutes to build,
and that’s with the Docker cache being busted early on. Most builds should
be able to use layer cache up until the COPY . /usr/src/app
step.
Zaaaaaaaaaaaaangggggggg.
FROM ruby:2.6.4
LABEL maintainer='frank@larvata.tw'
RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \
tzdata \
libsodium23
COPY Gemfile* /usr/src/app/
COPY vendor/cache /usr/src/app/vendor/cache
WORKDIR /usr/src/app
RUN bundle install --deployment --local --without development test
COPY . /usr/src/app/
EXPOSE 50051
CMD ["bin/rails", "s"]