Search code examples
ruby-on-railsrubydockerrubygems

How can I overcome Nokogiri dependency when dockerizing Ruby on Rails APi


I've been working on dockerizing a simple Ruby on Rails API with a SQL database, and I've been encountering the following error:

ERROR: It looks like you're trying to use Nokogiri as a precompiled native gem on a system with glibc < 2.17:
/lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /usr/local/bundle/gems/nokogiri-1.13.3-aarch64-linux/lib/nokogiri/3.0/nokogiri.so) - /usr/local/bundle/gems/nokogiri-1.13.3-aarch64-linux/lib/nokogiri/3.0/nokogiri.so
   If that's the case, then please install Nokogiri via the `ruby` platform gem:      gem install nokogiri --platform=ruby   or:  bundle config set force_ruby_platform true
Please visit https://nokogiri.org/tutorials/installing_nokogiri.html for more help.

Here's my dockerfile

FROM ruby:3.0.0

RUN apt-get update && apt-get install -y build-essential
RUN apt-get install default-mysql-client -y

RUN mkdir /task
WORKDIR /task

ADD Gemfile /task/Gemfile
ADD Gemfile.lock /task/Gemfile.lock

RUN bundle install

ADD . /task

And here's my compose file

services:
  db:
    platform: linux/x86_64
    image: mysql:8.0.20
    restart: always
    environment:
      MYSQL_USER: root
      MYSQL_DB: chat_system
      MYSQL_HOST: db
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3307:3306"
  app:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ".:/noteapp"
    ports:
      - "3001:3000"
    depends_on:
      - db
    links:
      - db
    environment:
      DB_USER: root
      DB_NAME: chat_system
      DB_PASSWORD: password
      DB_HOST: db

Gemfile

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.0"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.2", ">= 7.0.2.3"

# Use mysql as the database for Active Record
gem "mysql2", "~> 0.5"

# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.0"

# Build JSON APIs with ease [https://github.com/rails/jbuilder]
# gem "jbuilder"

# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false

gem 'redis'
gem 'redis-namespace'
gem 'redis-rails'
gem 'redis-rack-cache'
gem 'sneakers'
gem 'bunny'

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem "rack-cors"

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
end

group :development do
  # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
  # gem "spring"
end

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    actioncable (7.0.2.3)
      actionpack (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (7.0.2.3)
      actionpack (= 7.0.2.3)
      activejob (= 7.0.2.3)
      activerecord (= 7.0.2.3)
      activestorage (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      mail (>= 2.7.1)
      net-imap
      net-pop
      net-smtp
    actionmailer (7.0.2.3)
      actionpack (= 7.0.2.3)
      actionview (= 7.0.2.3)
      activejob (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      mail (~> 2.5, >= 2.5.4)
      net-imap
      net-pop
      net-smtp
      rails-dom-testing (~> 2.0)
    actionpack (7.0.2.3)
      actionview (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      rack (~> 2.0, >= 2.2.0)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
    actiontext (7.0.2.3)
      actionpack (= 7.0.2.3)
      activerecord (= 7.0.2.3)
      activestorage (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      globalid (>= 0.6.0)
      nokogiri (>= 1.8.5)
    actionview (7.0.2.3)
      activesupport (= 7.0.2.3)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    activejob (7.0.2.3)
      activesupport (= 7.0.2.3)
      globalid (>= 0.3.6)
    activemodel (7.0.2.3)
      activesupport (= 7.0.2.3)
    activerecord (7.0.2.3)
      activemodel (= 7.0.2.3)
      activesupport (= 7.0.2.3)
    activestorage (7.0.2.3)
      actionpack (= 7.0.2.3)
      activejob (= 7.0.2.3)
      activerecord (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      marcel (~> 1.0)
      mini_mime (>= 1.1.0)
    activesupport (7.0.2.3)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 1.6, < 2)
      minitest (>= 5.1)
      tzinfo (~> 2.0)
    amq-protocol (2.3.2)
    bootsnap (1.11.1)
      msgpack (~> 1.2)
    builder (3.2.4)
    bunny (2.19.0)
      amq-protocol (~> 2.3, >= 2.3.1)
      sorted_set (~> 1, >= 1.0.2)
    concurrent-ruby (1.1.10)
    crass (1.0.6)
    debug (1.5.0)
      irb (>= 1.3.6)
      reline (>= 0.2.7)
    digest (3.1.0)
    erubi (1.10.0)
    globalid (1.0.0)
      activesupport (>= 5.0)
    i18n (1.10.0)
      concurrent-ruby (~> 1.0)
    io-console (0.5.11)
    irb (1.4.1)
      reline (>= 0.3.0)
    loofah (2.16.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (1.0.2)
    method_source (1.0.0)
    mini_mime (1.1.2)
    minitest (5.15.0)
    msgpack (1.5.1)
    net-imap (0.2.3)
      digest
      net-protocol
      strscan
    net-pop (0.1.1)
      digest
      net-protocol
      timeout
    net-protocol (0.1.3)
      timeout
    net-smtp (0.3.1)
      digest
      net-protocol
      timeout
    nio4r (2.5.8)
    nokogiri (1.13.3-arm64-darwin)
      racc (~> 1.4)
    puma (5.6.4)
      nio4r (~> 2.0)
    racc (1.6.0)
    rack (2.2.3)
    rack-cache (1.13.0)
      rack (>= 0.4)
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (7.0.2.3)
      actioncable (= 7.0.2.3)
      actionmailbox (= 7.0.2.3)
      actionmailer (= 7.0.2.3)
      actionpack (= 7.0.2.3)
      actiontext (= 7.0.2.3)
      actionview (= 7.0.2.3)
      activejob (= 7.0.2.3)
      activemodel (= 7.0.2.3)
      activerecord (= 7.0.2.3)
      activestorage (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      bundler (>= 1.15.0)
      railties (= 7.0.2.3)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.4.2)
      loofah (~> 2.3)
    railties (7.0.2.3)
      actionpack (= 7.0.2.3)
      activesupport (= 7.0.2.3)
      method_source
      rake (>= 12.2)
      thor (~> 1.0)
      zeitwerk (~> 2.5)
    rake (12.3.3)
    rbtree (0.4.5)
    redis (4.6.0)
    redis-actionpack (5.3.0)
      actionpack (>= 5, < 8)
      redis-rack (>= 2.1.0, < 3)
      redis-store (>= 1.1.0, < 2)
    redis-activesupport (5.3.0)
      activesupport (>= 3, < 8)
      redis-store (>= 1.3, < 2)
    redis-namespace (1.8.2)
      redis (>= 3.0.4)
    redis-rack (2.1.4)
      rack (>= 2.0.8, < 3)
      redis-store (>= 1.2, < 2)
    redis-rack-cache (2.2.1)
      rack-cache (>= 1.10, < 2)
      redis-store (>= 1.6, < 2)
    redis-rails (5.0.2)
      redis-actionpack (>= 5.0, < 6)
      redis-activesupport (>= 5.0, < 6)
      redis-store (>= 1.2, < 2)
    redis-store (1.9.1)
      redis (>= 4, < 5)
    reline (0.3.1)
      io-console (~> 0.5)
    serverengine (2.1.1)
      sigdump (~> 0.2.2)
    set (1.0.2)
    sigdump (0.2.4)
    sneakers (2.12.0)
      bunny (~> 2.14)
      concurrent-ruby (~> 1.0)
      rake (~> 12.3)
      serverengine (~> 2.1.0)
      thor
    sorted_set (1.0.3)
      rbtree
      set (~> 1.0)
    strscan (3.0.1)
    thor (1.2.1)
    timeout (0.2.0)
    tzinfo (2.0.4)
      concurrent-ruby (~> 1.0)
    websocket-driver (0.7.5)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    zeitwerk (2.5.4)

PLATFORMS
  arm64-darwin-21

DEPENDENCIES
  bootsnap
  bunny
  debug
  puma (~> 5.0)
  rails (~> 7.0.2, >= 7.0.2.3)
  redis
  redis-namespace
  redis-rack-cache
  redis-rails
  sneakers
  tzinfo-data

RUBY VERSION
   ruby 3.0.0p0

BUNDLED WITH
   2.2.3


Note that I am working on a M1 Macbook Machine I am still new to Ruby so it might be a stupid issue that's causing all this hassle


Solution

  • Looks like this is indeed caused by the fact that you are on an ARM platform (Mac M1 being ARM processors).

    This is also somehow shown by that path in your error message:

    /usr/local/bundle/gems/nokogiri-1.13.3-aarch64-linux/lib/nokogiri/3.0/nokogiri.so

    aarch64 being another name of the ARM 64 bits architecture.

    In order to overcome this, you will have to use the same trick you used for your MySQL container: swap it to a linux/x86_64 platform.

    So, in your docker-compose.yml, you should have:

    ## the file above this stays the same
      app:
        platform: linux/x86_64
    ## the file below this stays the same
    

    And adapt your Gemfile.lock, the line

        nokogiri (1.13.3-arm64-darwin)
    

    Should become

        nokogiri (1.13.3-x86_64-linux)
    

    Then, at least rebuild that container:

    docker compose down
    docker compose up --build