部署至fly.io时遭遇Rubygems Net::OpenTimeout问题求助
问题描述
部署Rails应用到fly.io时,更新已有应用或部署新应用都会触发网络超时错误:
=> ERROR [base 5/5] RUN gem update --system --no-document && gem install -N bundler -v 2.2.33 60.9s ------ > [base 5/5] RUN gem update --system --no-document && gem install -N bundler -v 2.2.33: #10 60.85 ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError) #10 60.85 Net::OpenTimeout: execution expired (https://rubygems.org/specs.4.8.gz) ------ Error failed to fetch an image or build from source: error building: executor failed running [/bin/bash -o pipefail -c gem update --system --no-document && gem install -N bundler -v ${BUNDLER_VERSION}]: exit code: 1
问题根源是bundler优先尝试IPv6连接rubygems.org,解析失败后未及时切换到IPv4就超时。本地的解决方法不适用fly.io的Docker构建环境,进一步排查发现fly.io使用账户下的远程构建器完成镜像构建,问题出在该构建器无法正常访问rubygems.org。
解决方案
方法1:强制RubyGems用IPv4访问
在Dockerfile的gem命令前添加环境变量,强制走IPv4:
# 方式一:设置全局环境变量 ENV RUBY_GEMS_IPV4_ONLY=1 RUN gem update --system --no-document && \ gem install -N bundler -v ${BUNDLER_VERSION} # 方式二:仅在执行gem命令时临时设置 RUN RUBY_GEMS_IPV4_ONLY=1 gem update --system --no-document && \ RUBY_GEMS_IPV4_ONLY=1 gem install -N bundler -v ${BUNDLER_VERSION}
方法2:切换RubyGems源到国内镜像
如果IPv4访问rubygems.org还是有问题,可临时换成国内镜像源(比如清华镜像):
RUN gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://rubygems.org/ && \ gem update --system --no-document && \ gem install -N bundler -v ${BUNDLER_VERSION} # 可选:部署完成后切回官方源 # RUN gem sources --add https://rubygems.org/ --remove https://mirrors.tuna.tsinghua.edu.cn/rubygems/
方法3:通过fly.toml配置构建环境
在fly.toml中添加构建参数,让远程构建器自动启用IPv4强制:
[build] [build.args] RUBY_GEMS_IPV4_ONLY = "1"
这样Dockerfile无需修改,构建时会自动继承这个环境变量。
方法4:本地构建镜像后推送
如果远程构建器网络问题持续,直接在本地构建镜像再推送到fly.io:
# 本地构建镜像 docker build -t my-rails-app . # 登录fly.io镜像仓库 fly auth docker # 给镜像打标签 docker tag my-rails-app registry.fly.io/你的应用名称:latest # 推送镜像 docker push registry.fly.io/你的应用名称:latest # 部署推送好的镜像 fly deploy --image registry.fly.io/你的应用名称:latest
内容的提问来源于stack exchange,提问作者Brad
相关产品推荐
相关产品推荐

