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