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
相关产品推荐
相关产品推荐

