相同Docker配置下Mac与Ubuntu VPS执行bundle install结果不一致
Ruby Docker环境跨设备构建sassc报错问题解答
问题背景
使用以下Dockerfile和docker-compose.yml配置构建Ruby开发环境:
Dockerfile
FROM ruby:2.6.3-alpine ENV BUNDLER_VERSION=2.2.6 RUN apk add --update --no-cache \ binutils-gold \ build-base \ curl \ file \ g++ \ gcc \ git \ less \ libstdc++ \ libffi-dev \ libc-dev \ linux-headers \ libxml2-dev \ libxslt-dev \ libgcrypt-dev \ make \ netcat-openbsd \ nodejs \ openssl \ pkgconfig \ postgresql-dev \ python \ tzdata \ yarn RUN gem install bundler -v 2.2.6 WORKDIR /app COPY Gemfile Gemfile.lock ./ RUN bundle config build.nokogiri --use-system-libraries RUN bundle check || bundle install COPY package.json yarn.lock ./ RUN yarn install --check-files COPY . ./ ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]
docker-compose.yml
version: '3.4' services: app: build: context: . dockerfile: Dockerfile depends_on: - database - redis ports: - "3000:3000" volumes: - .:/app - gem_cache:/usr/local/bundle/gems - node_modules:/app/node_modules env_file: .env environment: RAILS_ENV: development database: image: postgres:12.1 volumes: - db_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: - "5432:5432" redis: image: redis:5.0.7 sidekiq: build: context: . dockerfile: Dockerfile depends_on: - app - database - redis volumes: - .:/app - gem_cache:/usr/local/bundle/gems - node_modules:/app/node_modules env_file: .env environment: RAILS_ENV: development entrypoint: ./entrypoints/sidekiq-entrypoint.sh volumes: gem_cache: db_data: node_modules:
故障现象
- 相同配置在Mac设备上构建运行完全正常
- 在Ubuntu系统VPS上构建时,sassc依赖始终抛出
Failed to build gem native extension错误,更换sassc版本也无法解决
故障根因
1. Gemfile.lock平台不匹配
Mac本地生成的Gemfile.lock中PLATFORMS字段仅记录了Mac对应的平台标识(x86_64-darwin/arm64-darwin),缺少Linux容器需要的x86_64-linux或aarch64-linux平台信息。Bundler在Linux环境运行时无法找到对应平台的预编译sassc包,会触发原生扩展源码编译流程。
2. 旧版sassc与Alpine musl libc兼容问题
你使用的Ruby 2.6.3配套的sassc版本通常较旧,其内置的libsass源码与Alpine系统使用的musl libc存在编译兼容问题,原生扩展编译直接失败。Mac上的Docker Desktop自带架构兼容适配层,会自动规避部分编译问题,因此不会触发报错。
3. 架构差异(若VPS为ARM架构)
如果你的Ubuntu VPS是ARM架构(如ARM64),旧版sassc未提供适配ARM架构+musl libc的预编译包,编译阶段会触发额外的架构兼容错误,直接导致构建失败。
4. 缓存卷干扰
若Ubuntu VPS上残留了之前构建的gem_cache卷缓存,其中可能包含损坏的原生扩展文件,重复构建时会优先读取缓存的错误文件,导致即使更换sassc版本也无法修复问题。
修复方案
- 本地执行
bundle lock --add-platform x86_64-linux --add-platform aarch64-linux,更新Gemfile.lock的支持平台后再提交构建 - 在Dockerfile的apk安装步骤中添加
libsass-dev依赖,使用系统预装的libsass编译sassc - 构建前清理VPS上的旧缓存:
docker volume rm <你的项目名>_gem_cache,或构建时添加--no-cache参数跳过缓存
内容的提问来源于stack exchange,提问作者CoolDrinE
相关产品推荐
相关产品推荐

