Context
When switching a rails API from the docker image ruby:2.7.2
to the ruby:2.7.2-alpine
, I ran into a docker build
failure while executing the bundle install
step in the following Dockerfile
:
FROM ruby:2.7.2-alpine
RUN bundle config set deployment 'true'
ENV RAILS_ENV=production \
SECRET_KEY_BASE="dummy" \
LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3
WORKDIR /app
COPY . .
RUN bundle install
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "--log-to-stdout"]
And the error (trimmed down to show relevant parts only) I was getting when running docker build -t api .
was:
docker build -t api .
[+] Building 9.9s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
...
=> CACHED [3/5] WORKDIR /app 0.0s
=> [4/5] COPY . . 0.1s
=> ERROR [5/5] RUN bundle install 9.7s
------
> [5/5] RUN bundle install:
#9 2.156 Fetching gem metadata from https://rubygems.org/...........
#9 3.592 Fetching rake 13.0.3
#9 3.668 Installing rake 13.0.3
...
#9 9.329 Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
#9 9.329
#9 9.329 current directory:
#9 9.329 /app/vendor/bundle/ruby/2.7.0/gems/racc-1.5.2/ext/racc/cparse
#9 9.329 /usr/local/bin/ruby -I /usr/local/lib/ruby/2.7.0 -r
#9 9.329 ./siteconf20210402-1-1ym2trh.rb extconf.rb
#9 9.329 checking for rb_ary_subseq()... *** extconf.rb failed ***
...
#9 9.329 You have to install development tools first.
...
The interesting part is the line #9 9.329 You have to install development tools first.
. With the focus on minimal sized images, alpine
doesn’t ship the development libraries in the docker image, so you have to install them if you have code that depends on them.
Solution
The solution, then, is to add the build-base
package before running bundle install
, by adding the line RUN apk update && apk add --no-cache build-base
, as shown in the Dockerfile
below:
FROM ruby:2.7.2-alpine
RUN apk update && apk add --no-cache build-base
RUN bundle config set deployment 'true'
ENV RAILS_ENV=production \
SECRET_KEY_BASE="dummy" \
LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3
WORKDIR /app
COPY . .
RUN bundle install
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "--log-to-stdout"]
And voilĂ , the docker build
command should work now!