Gem 30 分钟搭建私有 Gems 源

42thcoder for 大搜车 · 发布于 2016年08月10日 · 最后由 zouchaoge 回复于 2016年09月21日 · 4763 次阅读
6764
本帖已被设为精华帖!

随着公司的高速发展, 公有 Gems 已经不太能满足需求, 尝试了下搭建私有 Gems 源, 分享下过程, 避免后来人踩坑.

需求

我们的需求比较简单:

  • 支持官方 RubyGems 的 Proxy. 也就是说我从私有源安装 Gem, 会自动代理到官方源, 然后保存到私有源.
  • 速度快, 无需人工维护
  • 可以发布私有 Gems
  • 基本的鉴权

综合以上考虑, 最终选择了geminabox

准备工作

首先呢, 你需要一台国际服务器, 推荐阿里云的香港服务器, 速度快到飞起.

初始化好机器, 安装好:

  • Ruby, 推荐 2.3.1
  • Nginx

代码

一个简单的 rack 应用, 就足够了.

require 'geminabox'

config = {
  data:          'data',
  views:         'views', # 如果没有页面, views 和 public_folder 可以注释掉.
  public_folder: 'public'
}

config.each do |method, location|
  Geminabox.send("#{method}=", File.expand_path(location, File.dirname(__FILE__)))
end

Geminabox.rubygems_proxy = true


run Geminabox::Server

rack 的 adapter 打算用 thin, 配置文件如下:

---
chdir: "/home/souche/souche_gems"
environment: production
timeout: 30
log: "/home/souche/souche_gems/log/thin.log"
pid: tmp/pids/thin.pid
max_conns: 1024
max_persistent_conns: 100
require: []
wait: 30
threadpool_size: 20
servers: 3
rackup: config.ru
socket: "./tmp/thin.sock"
daemonize: true

鉴权

两个地方需要鉴权: 获取 Gem 和发布 Gem. 不打算搞得很复杂, 暂时用 Nginx 的鉴权. 如果不需要鉴权, 下面配置中的 /souche 可以省去 auth 部分.

鉴权的效果是访问 /souche/ 下的 path 会要求鉴权信息, 其他 path 会直接返回 404.

Nginx 配置如下, 其中 auth_basic_user_file 文件中, 放置加密后的用户名和密码.

htpasswd 生成器: http://tool.oschina.net/htpasswd

upstream rack_upstream {
  server unix:/home/souche/souche_gems/tmp/thin.0.sock;
  server unix:/home/souche/souche_gems/tmp/thin.1.sock;
  server unix:/home/souche/souche_gems/tmp/thin.2.sock;
}

server {
  root /home/souche/souche_gems/public;
  listen       80;
  server_name  domain.tld;
  charset UTF-8;

  location ~* \.(js|jpg|png|css)$ {
    root /home/souche/souche_gems/public;
  }
  location /souche {
    auth_basic "Private Souche Gems";
    auth_basic_user_file /home/souche/souche_gems/auth.htpasswd;
    rewrite ^/souche/(.*) /$1 break;
    proxy_pass http://rack_upstream;
    proxy_redirect     off;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  }

  location / {
    return 404;
  }


   error_page 500 502 503 504 /500.html;
   client_max_body_size 4G;
   keepalive_timeout 10;
}

这个鉴权比较简单, 建议再增加内网限制的加权.

客户端使用

安装

想要使用私有源, source 都要替换为 http://user_name:password@souche.gems.com/souche.

安装单个 Gem: gem install grape --clear-sources --source http://user_name:password@souche.gems.com/souche

发布

私有 Gem 的发布有两种方法:

  • gem push pkg/my-awesome-gem-1.0.gem --host HOST
  • gem inabox pkg/my-awesome-gem-1.0.gem

前者的 HOST 需要跟 source 一致, 后者会提示你输入配置在 htpasswd 中的用户名和密码.

前端页面

geminabox 内置了两个页面: Gem 列表和上传 Gem. 感兴趣可以参考这个项目: https://github.com/geminabox/geminabox-bootstrap

配好的效果是这样的:

最后, 放个硬广: https://ruby-china.org/topics/30765

共收到 14 条回复
De6df3 huacnlee 将本帖设为了精华贴 08月10日 17:48
18930

阿里云的网络环境挺麻烦, 之前配置翻墙VPN 时候因为网络段被坑了一次, 其他几家会简单一些.

18605

auth.htpasswd 是从 http://tool.oschina.net/htpasswd 这里获得 的吗 ,这个地方能否解释一下哦 楼主

6764

#3楼 @geeker4py

Nginx 的鉴权是基于 HTTP Basic Auth. 用户名和密码通过 htpasswd 工具加密后, 存储在 auth.htpasswd 文件里面.

6764

#2楼 @ssybb1988

其他几家是啥, 大神给推荐下呗

8

https://ruby-china.org/topics/25124

支持官方 RubyGems 的 Proxy. 也就是说我从私有源安装 Gem, 会自动代理到官方源, 然后保存到私有源

可以在Gemfile指定多个source解决吧

6764

#6楼 @hooopo 一行流, 🆒

是的, 指定多个 source 可以达到 Proxy 的效果

681

下载过的gem可以自动缓存在本地吗?

6764

#8楼 @sevk

会的, 只要开启了 Geminabox.rubygems_proxy = true, 默认缓存在 data 文件夹下.

2376

可以试试 gemstash 是bundler官方推荐的

2376

#11楼 @sevk 只是跑server的ruby必须是ruby .2.2, 在ruby 2.3的项目中, 用这个gem server 尚未碰到问题

96

针对这个情况,个人比较倾向于 在github等平台 创建私有项目,Gemfile 中 gem 'xxx', git: 'xxx', ref: 'xxx' 。基于各平台的认证且不用维护私有mirror

96

学习了!!

6812

mark一下,回头自己试试

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