Docker-alpine: Unable to install ruby gem 'nokogiri'

Created on 23 Jul 2015  路  22Comments  路  Source: gliderlabs/docker-alpine

Hi, I am using base image of gliderlabs/alpine:3.1, and found that not able to instal ruby gems nokogiri.

My Dockerfile

RUN apk add --update \
  bash \
  ca-certificates \
  libxml2 \
  libxslt \
  gcc \
  ruby \
  ruby-bundler \
  ruby-dev \
  nodejs \
  mysql-client \
  imagemagick \
  nginx \
  && rm -rf /var/cache/apk/* \
  && adduser -D app \
  && gem install bundler --no-document \
  && gem install rails nokogiri \
  && npm install -g react-tools babel

As I want to install nokogiri, following error shows:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.>

    /usr/bin/ruby extconf.rb
 Building nokogiri using packaged libraries.
 -----
 libiconv is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
 -----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/bin/ruby
    --help
    --clean
    --use-system-libraries
    --enable-static
    --disable-static
    --with-zlib-dir
    --without-zlib-dir
    --with-zlib-include
    --without-zlib-include=${zlib-dir}/include
    --with-zlib-lib
    --without-zlib-lib=${zlib-dir}/lib
    --enable-cross-build
    --disable-cross-build

 extconf failed, exit code 1

Gem files will remain installed in /home/app/webapp/vendor/bundle/ruby/2.1.0/gems/nokogiri-1.6.3.1 for inspection.
Results logged to /home/app/webapp/vendor/bundle/ruby/2.1.0/extensions/x86_64-linux/2.1.0/nokogiri-1.6.3.1/gem_make.out
An error occurred while installing nokogiri (1.6.3.1), and Bundler cannot
continue.

Is there any way to avoid this?

Most helpful comment

Thanks @joffotron and @mattaitchison, this fixed it for me:

FROM ruby:2.3.0-alpine
# ...
RUN apk add --update \
  build-base \
  libxml2-dev \
  libxslt-dev \
  postgresql-dev \
  && rm -rf /var/cache/apk/*

# Use libxml2, libxslt a packages from alpine for building nokogiri
RUN bundle config build.nokogiri --use-system-libraries

All 22 comments

Hi, (caveat - beginner docker user),
I have managed to successfully install nokogiri on alpine 3.2 by using the package name ruby-nokogiri (see packages listing). That is, via Dockerfile:

RUN apk add ruby ruby-nokogiri

maybe that helps?

Hi robstwd,

I have tried your settings of installing ruby-nokogiri and always succeeded. But if I install nokogiri using gem install nokogiri, same error message appears again. Since rub-nokogiri is able to be installed, is there anything configuration for using command gem install nokogiri?

Error messages:

Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
    ERROR: Failed to build gem native extension.

    /usr/bin/ruby -r ./siteconf20150728-23-3hyhcz.rb extconf.rb
checking if the C compiler accepts ... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/bin/$(RUBY_BASE_NAME)
    --help
    --clean
/usr/lib/ruby/2.2.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /usr/lib/ruby/2.2.0/mkmf.rb:571:in `block in try_compile'
    from /usr/lib/ruby/2.2.0/mkmf.rb:522:in `with_werror'
    from /usr/lib/ruby/2.2.0/mkmf.rb:571:in `try_compile'
    from extconf.rb:80:in `nokogiri_try_compile'
    from extconf.rb:87:in `block in add_cflags'
    from /usr/lib/ruby/2.2.0/mkmf.rb:619:in `with_cflags'
    from extconf.rb:86:in `add_cflags'
    from extconf.rb:337:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /usr/lib/ruby/gems/2.2.0/gems/nokogiri-1.6.6.2 for inspection.
Results logged to /usr/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0/nokogiri-1.6.6.2/gem_make.out

ok, sorry well in that case, I have no more ideas.

OK, got it.

BTW, where does libraries installed by apk add in alpine linux? Maybe I can reference ruby-nokogiri to find out how to setup libraries when using command gem install nokogiri?

Not sure if this is what you mean, but on my alpine container with ruby-nokogiri successfully installed, the output of gem env is:

bash-4.3# gem env
RubyGems Environment:
  - RUBYGEMS VERSION: 2.4.5
  - RUBY VERSION: 2.2.2 (2015-04-13 patchlevel 95) [x86_64-linux-musl]
  - INSTALLATION DIRECTORY: /usr/lib/ruby/gems/2.2.0
  - RUBY EXECUTABLE: /usr/bin/ruby
  - EXECUTABLE DIRECTORY: /usr/bin
  - SPEC CACHE DIRECTORY: /root/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /usr/lib/ruby/gems/2.2.0
     - /root/.gem/ruby/2.2.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /usr/local/sbin
     - /usr/local/bin
     - /usr/sbin
     - /usr/bin
     - /sbin
     - /bin

I found from following link that some library need to be set in order to install nokogiri:

gem install nokogiri -- \
    --use-system-libraries \
    --with-iconv-dir=/path/to/dir \
    --with-zlib-dir=/path/to/dir \
    --with-xml2-config=/path/to/xml2-config \
    --with-xslt-config=/path/to/xslt-config

Can I know how ruby-nokogiri is set for those libraries?

Building native extensions requires certain system libraries and the build-base package.

You can see how ruby-nokogiri is built and what dependencies are required by looking at its APKBUILD file. View Here

Feel free to reopen this issue if you are still having problems.

nokogiri now bundles its own libxml2, which doesn't compile on alpine (looks like a pthreads thing maybe?). You can get it to use the libxml2(-dev) package on Alpine by:

gem install nokogiri --use-system-libraries

or

bundle config build.nokogiri --use-system-libraries
bundle install

Hopefully this helps someone else looking for help.

I did the same test first before running "bundle install" with "gem install bundler"

best regard

Adding libxml2-dev libxslt-dev to apk add fixed it for me..

Thanks @joffotron and @mattaitchison, this fixed it for me:

FROM ruby:2.3.0-alpine
# ...
RUN apk add --update \
  build-base \
  libxml2-dev \
  libxslt-dev \
  postgresql-dev \
  && rm -rf /var/cache/apk/*

# Use libxml2, libxslt a packages from alpine for building nokogiri
RUN bundle config build.nokogiri --use-system-libraries

Cool!

As of nokogiri 1.6.8, the --use-system-libraries work-around is unnecessary.

Thanks @ruudud my build was actually failing when I used --use-system-libraries and I needed to remove that in order to have succesful build.

Cleaner version of Dockerfile for nokogiri.

FROM ruby:2.5-alpine
# ...
RUN apk add --no-cache \
  build-base \
  libxml2-dev \
  libxslt-dev
# ...

Update:
@kylev add document for this issue. Refer to https://github.com/gliderlabs/docker-alpine/issues/53#issuecomment-532467114

In my case RUN apk update && apk add build-base was enough to install nokogiri 1.8.2 because:

In Nokogiri 1.6.0 and later libxml2 and libxslt are bundled with the gem, ...

source: https://github.com/sparklemotion/nokogiri#requirements

Basically

FROM ruby:2.3-alpine

RUN mkdir /usr/src/app \
    && chown $(id -un):$(id -gn) /usr/src/app \
    && apk add --no-cache build-base \
    && gem install bundler

ENV RAILS_ENV=development

COPY . /usr/src/app

RUN cd /usr/src/app \
    && bundle install --no-color

WORKDIR /usr/src/app
EXPOSE 3000
CMD ["bundle", "exec", "rake", "server"]

This works for me

RUN apk update && apk upgrade

RUN apk add ruby=2.5.2-r0 ruby-bundler ruby-nokogiri ruby-dev build-base libxml2-dev libxslt-dev libffi-dev

This is what I got to work with ruby:2.6-alpine.

$ docker run --rm -it -e PS1='# ' ruby:2.6-alpine sh
# apk add --no-cache --virtual .ruby-gemdeps libc-dev gcc libxml2-dev libxslt-dev make
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz
(1/17) Installing musl-dev (1.1.22-r2)
(2/17) Installing libc-dev (0.7.1-r0)
(3/17) Installing binutils (2.32-r0)
(4/17) Installing isl (0.18-r0)
(5/17) Installing libgomp (8.3.0-r0)
(6/17) Installing libatomic (8.3.0-r0)
(7/17) Installing mpfr3 (3.1.5-r1)
(8/17) Installing mpc1 (1.1.0-r0)
(9/17) Installing gcc (8.3.0-r0)
(10/17) Installing libxml2 (2.9.9-r2)
(11/17) Installing libxml2-dev (2.9.9-r2)
(12/17) Installing libgpg-error (1.36-r2)
(13/17) Installing libgcrypt (1.8.4-r1)
(14/17) Installing libxslt (1.1.33-r1)
(15/17) Installing libxslt-dev (1.1.33-r1)
(16/17) Installing make (4.2.1-r2)
(17/17) Installing .ruby-gemdeps (20190713.081810)
Executing busybox-1.30.1-r2.trigger
OK: 131 MiB in 54 packages
# gem install nokogiri -- --use-system-libraries
Fetching nokogiri-1.10.3.gem
Fetching mini_portile2-2.4.0.gem
Successfully installed mini_portile2-2.4.0
Building native extensions with: '--use-system-libraries'
This could take a while...
Successfully installed nokogiri-1.10.3
2 gems installed
#

This worked for me,

RUN apk add --no-cache build-base

Here is the reference Installing Nokogiri

I added additional documentation (as @gr1d99 mentioned) in sparklemotion/nokogiri.org#23

Was this page helpful?
0 / 5 - 0 ratings