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

jicheng1014 · December 29, 2021 · Last by jicheng1014 replied at December 29, 2021 · 554 hits

文章来自我自己的 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。


发现楼主第二点已经说了

Reply to Rei

私有注册表多少钱。

Reply to pynix

像阿里云个人版是免费

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

Reply to xinyifly

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

You need to Sign in before reply, if you don't have an account, please Sign up first.