Docker化Ruby on Rails应用时Nokogiri依赖报错的解决求助
问题描述
本地环境:ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [arm64-darwin22, Rails 7.0.4.3
使用的Dockerfile:
FROM ruby:3.0.0 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml配置:
version: '3.5' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: password redis: image: redis command: redis-server volumes: - 'redis:/data' web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db - redis environment: - REDIS_URL_CACHING=redis://redis:6379/0 - DB_HOST=db - DB_USERNAME=postgres - DB_PASSWORD=password volumes: redis: postgres:
database.yml配置:
default: &default adapter: postgresql encoding: unicode host: <%= ENV.fetch("DATABASE_HOST") %> username: <%= ENV.fetch("DATABASE_USERNAME") %> password: <%= ENV.fetch("DATABASE_PASSWORD") %> pool: 5 development: <<: *default database: myapp_development test: <<: *default database: myapp_test
执行命令:
docker-compose builddocker-compose up
启动后报错:
| ERROR: It looks like you're trying to use Nokogiri as a precompiled native gem on a system |
|---|
| with an unsupported version of glibc. |
| /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /usr/local/bundle/gems/nokogiri-1.14.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so) - /usr/local/bundle/gems/nokogiri-1.14.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so |
my_rails_app-web-1 |
If that's the case, then please install Nokogiri via the rubyplatform 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.
已尝试gem install nokogiri --platform=ruby和bundle config set force_ruby_platform true,但错误依旧。
解决方案
问题核心是本地ARM64 macOS环境安装的Nokogiri预编译gem,与Docker容器内的glibc版本不兼容,再加上本地目录挂载到容器(volumes: - .:/myapp),容器优先使用本地的bundle缓存和已安装gem,导致容器内的配置不生效。按以下步骤解决:
清理本地bundle相关文件
- 删除本地
Gemfile.lock文件 - 删除本地
vendor/bundle目录(如果存在) - 执行
bundle config set force_ruby_platform true,确保本地bundle也使用ruby平台编译
- 删除本地
修改Dockerfile,在容器内配置bundle并添加编译依赖
在bundle install前添加bundle配置命令,同时安装编译ruby版Nokogiri所需的系统依赖:FROM ruby:3.0.0 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client # 添加编译ruby版Nokogiri的依赖 RUN apt-get install -y build-essential patch zlib1g-dev liblzma-dev WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock # 在容器内强制使用ruby平台 RUN bundle config set force_ruby_platform true RUN bundle install EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]重新构建并启动
- 执行
docker-compose build --no-cache,避免使用旧镜像缓存 - 执行
docker-compose up
- 执行
替代方案(无需编译Nokogiri)
如果不想编译ruby版Nokogiri,可以更换Ruby基础镜像为glibc版本≥2.29的镜像,比如ruby:3.0.0-slim-bullseye(bullseye系统的glibc版本更高),直接使用预编译的Nokogiri gem:
FROM ruby:3.0.0-slim-bullseye
内容的提问来源于stack exchange,提问作者Theopap
相关产品推荐
相关产品推荐

