Ruby 解决 bundle install 时, 因为网络原因无法安装 基于 github 的 gem 的问题

jicheng1014 · 2021年12月29日 · 最后由 jicheng1014 回复于 2021年12月29日 · 555 次阅读

文章来自我自己的 blog: https://blog.3qruok.com/posts/9

==========

随着 docker 部署越来越流行,现在特别大的概率出现使用 Docker 部署 rails 的项目。但是身在国内,难免会被网络状况影响。而由于 docker 打包是基于 docker 镜像本身的,而在镜像本身里,不太好处理网络互联互通的问题。

常规方式有下面几种:

  • . 在部署机的交换机中就解决网络互联互通问题 即部署机天然具有互联互通。这种解决方案适合部署机在自己的内网当中。此时我们只需要从上层的路由器处理好相关业务即可。如果条件允许,其实这种解决方案应是最优解。但是如果不具备条件,如部署机是在云平台上,那就没办法了。

  • . 将部署机直接部署到 hk 或 singapore 这种方式的好处在于 hk 或者 Singapore 的节点接入大陆的速度都还不错,连接 github 以及其他国外服务也很方便,是不错的选择。但缺点就是 费用稍高,再就是远离了生产环境,build 好的镜像回推又涉及跨网络处理。最后就是合规问题,有的项目可能会有要求。

我最近找到了第三种方案:利用 coding.net 同步 github 仓库的功能 这种方案是当以上两种条件均不满足时的策略,缺点是 多了一层对 coding 有依赖,并且会对 gemfile 进行一点点修改

整体的思路就是查找 Gemfile 中 使用了 github 地址的项目,在 coding 中建立镜像,再在 gemfile 中做修改

具体方案如下: 第一步:在 coding.net 中新建仓库,选择 从外部导入仓库

确定建立这个仓库,并重命名仓库,我这里强烈建议,将原来的 github 地址的“/”替换为“-”(如 github 里的地址是 guard/listen 则这里仓库名称改写为 guard-listen)以方便我们在 Gemfile 中做整体替换。另外需要确保新建的仓库打开了自动同步

之后,coding 就会帮我们自动镜像对应的仓库了。

第二步,修改 Gemfile,将具体的 github 地址改为 coding 的地址 这里就说明到最开始我为何重命名的时候有规律了。一般情况下,我们的 Gemfile 长这样

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.3"

gem "listen", github: "guard/listen"

此时我们看到这里的重点 git_source(:github)

我们可以改造这里,变为

git_source(:github) do |repo_name| 
  if ENV["GEM_GITHUB_PROXY"] == "1"
    "https://e.coding.net/gems-github-mirror/gems-mirror/#{repo_name.split("/").join("-")}.git"   # 此处需要确定你的 coding 仓库地址规则
  else
    "https://github.com/#{repo_name}.git" 
  end
end

再次强调,由于我之前设置 coding 的 repository 的名称是 将 / 替换为了 "-",所以我这里就可以直接生成对应的 coding 的仓库地址。

之后我们在 dockerfile 中加入环境变量 GEM_GITHUB_PROXY 就可以只在 docker 打包的时候,使用对应的代理了。如果你想一直走 coding 的代理,自然可以改造,直接返回 coding 的地址。

总结这个方式的优缺点

优点: 不依赖于其他网络技术,即可实现更新 Gemfile 中强依赖 github 的仓库。

缺点:

  1. 需要自己手动建立 github 对应的 coding 的仓库。
  2. 需要少量改变代码。

最后感慨一下,感觉网络互联互通问题是国内 docker 技术推广的最大的障碍。从拉镜像,到给镜像里装依赖,再到推镜像,再到部署,部署里又从搭建 k8s 到部署封装 helm 到最后到运维,基本上都会遇见网络互联互通问题。如果有哪家厂商能够从头到脚提供一揽子解决方案,或透明或超级简单配置后就能解决这些问题,肯定会超级受欢迎,至少我肯定会愿意付费使用。

在 github actions 里面构建镜像,然后推到云服务的 docker registry。


发现楼主第二点已经说了

Rei 回复

私有注册表多少钱。

pynix 回复

像阿里云个人版是免费

要不要考虑一下 iptables 方案?敏感话题就不公开讨论了,对这项技术感兴趣可以 PM 我。最近发现这个方案理解了的话,处理服务器访问互联网的问题超级容易。

xinyifly 回复

嗯嗯 我就是利用的 iptables 弄的 google oauth

需要 登录 后方可回复, 如果你还没有账号请 注册新账号