Install development tools in alpine


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!

References

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.