You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker构建Rails应用失败:bundle update net-pop退出码34求助

问题:Docker构建Ruby on Rails容器时bundle update net-pop失败(退出码34)

我执行以下命令构建Docker容器:

docker build --no-cache -t cryptoall .

但持续遇到错误,构建在Dockerfile第51步失败,错误输出如下:

43.55 (net-protocol (>= 0)).
43.55 Running `bundle update net-pop` should fix the problem.
------
Dockerfile:51
--------------------
 50 |     COPY Gemfile Gemfile.lock ./
 51 | >>> RUN bundle update net-pop && \
 52 | >>>     bundle install && \
 53 | >>>     rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
 54 | >>>     bundle exec bootsnap precompile --gemfile
 55 |     
--------------------
ERROR: failed to solve: process "/bin/sh -c bundle update net-pop &&     bundle install &&     rm -rf ~/.bundle/ \"${BUNDLE_PATH}\"/ruby/*/cache \"${BUNDLE_PATH}\"/ruby/*/bundler/gems/*/.git &&     bundle exec bootsnap precompile --gemfile" did not complete successfully: exit code: 34

对应的Dockerfile内容:

# syntax=docker/dockerfile:1

# This Dockerfile is designed for production, not development. Use with Kamal or 
# build'n'run by hand:
# docker build -t cryptoall .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name 
# cryptoall cryptoall

# For a containerized dev environment, see Dev Containers: 
# https://guides.rubyonrails.org/getting_started_with_devcontainer.html

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.3.3
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
WORKDIR /rails

# Install base packages
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Set production environment
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems, including dependencies for Nokogiri and others
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y \
      build-essential \
      libpq-dev \
      nodejs \
      npm \
      git \
      pkg-config \
      libxml2-dev \
      libxslt1-dev \
      liblzma-dev \
      libcurl4-openssl-dev \
      libssl-dev && \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# Install the correct version of Bundler
RUN gem install bundler -v 2.5.23

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle update net-pop && \
    bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Verify the rails executable is installed
RUN bundle exec rails --version

# Copy application code
COPY . /rails

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
# Use a dummy key for precompiling, this can be set during deployment
RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile

# Final stage for app image
FROM base

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Verify the rails executable is copied
RUN ls -l /rails/bin/rails

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
    chown -R rails:rails /rails/db /rails/log /rails/storage /rails/tmp
USER rails

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start server via Thruster by default, this can be overwritten at runtime
EXPOSE 80
CMD ["bundle", "exec", "/rails/bin/rails", "server", "-b", "0.0.0.0"]

错误摘要:构建卡在bundle update net-pop && bundle install...步骤,退出码34。错误提示运行bundle update net-pop可解决,但实际执行无效。

我已尝试的操作:

  • 在本地直接执行bundle update net-pop并更新其他gem
  • 确认已安装正确版本的Bundler(2.5.23)

请问该如何修复此问题,或是我的Dockerfile中存在遗漏的配置?


解决方案

1. 本地更新依赖后同步到容器构建

容器内开启BUNDLE_DEPLOYMENT=1的生产模式时,会严格遵循本地Gemfile.lock的版本约束,直接在容器内执行bundle update会受限。正确流程:

  • 本地开发环境执行bundle update net-pop,更新Gemfile.lock中的依赖版本
  • 将更新后的Gemfile和Gemfile.lock同步到项目中,修改Dockerfile对应步骤,去掉容器内的bundle update net-pop:
    # Install application gems
    COPY Gemfile Gemfile.lock ./
    RUN bundle install && \
        rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
        bundle exec bootsnap precompile --gemfile
    

2. 检查并修复net-protocol依赖冲突

错误提示提到(net-protocol (>= 0)),说明net-pop依赖的net-protocol版本不满足当前Gemfile.lock的约束:

  • 本地执行bundle info net-pop和bundle info net-protocol查看版本信息
  • 在Gemfile中明确指定net-protocol的兼容版本,比如:
    gem 'net-protocol', '>= 0.2.1'
    
  • 执行bundle install更新Gemfile.lock后,重新构建容器

3. 清理本地bundle缓存后重新生成依赖文件

本地缓存的旧依赖可能导致版本不一致,执行以下命令重置:

bundle clean --force
bundle update net-pop

提交新生成的Gemfile.lock后,再进行Docker构建

4. 临时调整容器内的Bundler部署模式(不推荐)

如果必须在容器内执行更新,可临时关闭生产环境的严格部署模式:
修改build阶段的ENV配置:

# Set production environment (build阶段临时调整)
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="0" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"

执行完bundle update net-pop && bundle install后,再重新设置BUNDLE_DEPLOYMENT=1,但此方式会破坏生产环境依赖的确定性,仅作为临时方案。


内容的提问来源于stack exchange,提问作者Augusto Faggion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:34:52