scribble

ottocho's blog

Home About GitHub

23 Mar 2013
Build A Gems Server

搭建 gems 服务


前言

这篇文章记录下如何自己搭建一个gems server。

什么时候需要自建一个gems server?假设需要用到某服务,在部署和更新之时用自己的gems server提供包是一件非常正常而靠谱的事情。而对于ruby实现的服务,rvm基本是最佳实践了。在自建gems server的基础上部署rvm,可以对服务的部署和更新等有最根本和最方便的管理。

其实这个事情步骤很是简单,就是基本没有中文文档说明这个事情。rubygems官方文档也有一些说明。


自制gems

顺便在这里建一个超级简单的gem来测试。

文件如下:

.
|-- bin
|   `-- obin
|-- lib
|   `-- otto.rb
|-- otto-0.3.1.gem
`-- otto.gemspec

lib/otto.rb 实现

class Otto
    def self.fullname
        puts 'ottocho'
    end
end

otto.gemspec 声明

Gem::Specification.new do |s|
  s.name        = 'otto'
  s.version     = '0.3.1'
  s.date        = '2012-12-21'
  s.summary     = "test gem"
  s.description = "test gem"
  s.authors     = ["ottocho"]
  s.email       = 'otto.cho@live.cn'
  s.files       = ["lib/otto.rb"]
  s.homepage    = 'http://localhost'
  s.executables << 'obin'
end

极其简单的bin/obin

#!/usr/bin/env ruby

require 'rubygems'
require 'otto'

Otto.fullname

此时:

gem build otto.gemspec

应该会输出这个gem文件:

otto-0.3.1.gem

自建gem server

本质而言gem server为一个http文件服务。因此对于一个gem server而言,我们需要做的是提供一个gem install时需要获取的文件。

如本例中我用nginx提供文件服务 web root在此:

root /home/ottocho/www;

而:

mkdir /home/ottocho/www/gems

即,http://xxx/gems/ 提供gems

将gem放在提供服务的web root下

cp otto-0.3.1.gem /home/ottocho/www/gems/

每次更新web文件服务里面的gem文件 就generate_index一次

gem generate_index -d /home/ottocho/www/gems/

这就都搞定了,测试下

gem install otto -v '0.3.1' --source http://127.0.0.1/gems/

结语

其实自建一个gemserver的确很简单。但这个简单的步骤可以做非常多事情。例如我正在负责的puppet项目就很希望利用rvm和gem server来做部署与更新。但是现在在用的显然还勉强可以用。用gem server显然有更多的好处。

  1. 部署使用一个安装包当然是很正常的,但是如果将二进制(ruby等)和ruby代码都打包在一起,那么会失去灵活性。因为对于我们而言,二进制程序更新很少(ruby1.8换为1.9估计可以用两年了,2.0估计短时间内都不会生存环境使用),而ruby代码是经常会更新的,puppet版本我们是会需要偶尔更新的,而puppet源码修改和拓展的更新也因为固化的安装包变得无法操作。
  2. 现在的版本控制方案是使用一个crontab一直跑一个脚本,脚本参数指定一个版本数来重复检测和更新,这真是个很奇怪的事情。逻辑上就不正确:程序运行版本就应该在安装之时或者更新之时直接指定一个版本号,然后就完成了这么一个事情。一次性的工作为什么需要cron?ruby的管理,有rvm;gem的管理有rubygems和gemset。更新和切换,一条命令即可。

【完】

2013.03.23, ottocho


Til next time,
at 13:05

scribble

Home About GitHub