scribble

ottocho's blog

Home About GitHub

07 Apr 2013
RVM Tutorial

rvm 入门


前言

这篇文章是对我对rvm的一些研究的一些笔记。主要还是官方和自己踩的坑后所做的总结为主。感觉我可能很长一段时间都不会去倒腾rvm了,最后记下这个情况吧。

什么是rvm?rvm是用来切换多版本ruby和gem库的。对于蛋疼的ruby和gem而言,版本众多。在同一台机上如果需要部署不同版本的ruby,或者部署不同的ruby应用时却发现它们所依赖的gem间有冲突,此时,rvm是解决此类问题的最佳方法。

主要参考了下这个官方文档参考

本文基于Debian 6.0。但是我觉得其他版本也差得不太大。


过程

安装系统包

aptitude install build-essential openssl curl libcurl4-openssl-dev libreadline6 libreadline6-dev git zlib1g zlib1g-dev libssl-dev libyaml-dev libxml2-dev libxslt1-dev autoconf automake libtool imagemagick libmagickwand-dev libpcre3-dev curl sudo libruby zlib1g zlib1g-dev

注意,这里是配置的一个编译环境,而在生产环境上是不推荐配置有编译环境的(这不安全),也浪费资源。这里需要有编译环境的问题是rvm会去获取ruby源码而编译安装。因此在简单的rvm配置安装只能这样配置。

如果希望rvm安装ruby时可以直接获取二进制而不耗时编译,可以去更新 ~/.rvm/config/db配置,使用rvm install xxx 时指定参数--binary,直接获取二进制文件从而不再次编译。(具体配置哪个,我也不知道,虚拟机硬盘给挤爆了,今天懒得刷了,下次再测试,哈哈。)

安装方式

对于rvm而言,官方说明有三种安装方式(官方的第三种混合型基本忽视吧)。

单用户安装rvm的特点是rvm只允许安装用户使用,安装目录在 ~user/.rvm/ 中,因此这比较适合由一个用户来负责ruby服务的情况。

而多用户安装rvm的特点是所有用户都可以使用rvm工具,但是只有rvm组里的用户才有写权限(这个是由/etc/rvmrc的设置umask指定的)。另外,多用户安装的情况下rvm的配置文件即为/etc/rvmrc。而用户在登录时调用/etc/profile,从而调用/etc/profile.d/rvm.sh,因此非login的用户(su或其他)会需要source 下profile才能使用rvm。这可以在其他地方进行配置,显式source /etc/profile

还有一种方法是直接复制黏贴rvm的目录。简单方便。未普遍测试。

单用户部署 rvm

切记:不要用root帐号!!!

curl -L get.rvm.io | bash -s stable

它会安装在当前登录用户的.rvm目录下,并且以后安装的gem和ruby都在.rvm以内

更新一下 ~/.bashrc

echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.' >> ~/.bashrc

检查安装结果

rvm -v

多用户部署 rvm

__利用一个非root的用户,sudo安装。__rvm会被安装在 /usr/local/rvm 这个路径。

这样的多用户安装方法,使得所有用户都可以使用rvm工具,而且rvm安装在公共的目录中/usr/local/rvm/,但是只有rvm组里的用户才有写权限(这个是由/etc/rvmrc的设置umask指定的)。

root用户身份,添加puppet用户

mkdir /home/puppet
useradd puppet
chown –R /home/puppet puppet:puppet

root用户身份,为puppet用户添加sudo。__(这点官方文档没有提及,但这个非常重要)__配置文件/etc/sudoers添加了这么一句:

puppet  ALL=(root) ALL

su为puppet用户,进行rvm安装

su puppet -
curl -L https://get.rvm.io | sudo bash -s stable

root用户身份,更新puppet用户的用户组为root与rvm

usermod puppet -G root,rvm

su为puppet用户进行如下操作:

source /etc/profile

检查安装结果

rvm -v

直接复制部署 rvm

这个方法是我在下班路上突然想到的。这个方法基于多用户安装rvm的方法。

多用户安装rvm的方法中,我们可以得知rvm是安装在 /etc/local/rvm 中的。这不仅仅意味着rvm的可执行文件在此,利用rvm管理的ruby、gem、gemset都在此目录中。在利用rvm install安装ruby时,rvm会获取ruby源码进行编译,其编译输出也就放置在此目录中(如我测试所用jruby,其路径即为/usr/local/rvm/rubies/jruby-1.7.2/bin)。

因此在希望快速安装的时候,且在平台一致的情况下,对此目录及rvm的配置文件进行复制放置,就可以快速进行rvm部署了。

需要打包的文件:

/etc/rvmrc
/etc/profile.d/rvm.sh
/usr/local/rvm/*

放置在目标机器的对应目录即可。

因此如果需要对多个系统进行rvm部署(Debian5,6 FreeBSD),那就找测试机进行rvm安装,然后简单打个包就搞定了(只在Debian 6上测试可行)。


rvm的基本使用:

rvm安装ruby

首先替换 Ruby 下载地址到国内淘宝镜像服务器 ruby.taobao.org/mirrors/ruby。感谢淘宝对ruby社区的帮助,同时鄙视下某w。

# 单用户情况下,配置文件在 ~/.rvm/config 内
   sed -i 's/ftp\.ruby-lang\.org\/pub\/ruby/ruby\.taobao\.org\/mirrors\/ruby/g'  ~/.rvm/config/db
# 多用户情况下,配置文件在 /usr/local/rvm/config/ 内
   sed -i 's/ftp\.ruby-lang\.org\/pub\/ruby/ruby\.taobao\.org\/mirrors\/ruby/g'   /usr/local/rvm/config/db
# 安装 readline 包
$ rvm pkg install readline  # 这个前要先apt装好 libreadline
# 安装 Ruby 1.9.2
$ rvm install 1.9.2 --with-readline-dir=$rvm_path/usr
# 安装 Ruby 1.8.7
$ rvm install 1.8.7 --with-readline-dir=$rvm_path/usr

设置默认的ruby版本: (这里的ruby就是rvm设置的 而不用系统原安装的/usr/bin/ruby了.)

rvm 1.9.2 --default

ruby -v   #看看用了什么版本 看有没有问题

设置源的三步

gem -v
gem source -r https://rubygems.org/
gem source -a http://ruby.taobao.org

rvm配置gemset

当然,rvm最大的用处就是可以快速切换ruby和gemset。rvm use ...命令即为切换ruby和gemset。下面仅仅是非常简要的介绍一下。具体还是看看官方文档吧。

新建两个gemset的步骤如下:

切换到ruby版本1.8.7 然后新建gemset,切换到新建的gemset中

rvm use 1.8.7
rvm gemset create rails2.3.11
rvm use 1.8.7@rails2.3.11
gem install rails -v 2.3.11

如上 就新建了一个1.8.7的ruby配合2.3.11的rails的一个gemset

然后再新建一个gemset 1.9.3的ruby 配置rails3.2.8

# rvm install 1.9.3
rvm use 1.9.3
rvm gemset create rails3.2.8
rvm use 1.9.3@rails3.2.8
gem install rails -v 3.2.8

如上就新建了一个1.9.3的ruby配置3.2.8的rails的一个gemset

gemset是可以自动加载的。例如项目otc使用1.9.3@rails3.2.8gemset 可以在项目目录中写一个文件名为 .rvmrc的文件,内容如下:

rvm use 1.9.3@rails3.2.8

于是,当cd到这个项目的时候,就自动加载了这个ruby及gemset。

可以利用 rvm gemset list_all 命令输出所有的gemset,如下是在我的主机中的输出,使用的是单用户安装方法 :

$ rvm gemset list_all

gemsets for ruby-1.9.3-p327 (found in /home/ottocho/.rvm/gems/ruby-1.9.3-p327)
=> (default)
   global
   rails3.2.8
   sinatra
   todo


gemsets for ruby-1.8.7-p371 (found in /home/ottocho/.rvm/gems/ruby-1.8.7-p371)
=> (default)
   global
   puppet2.7.12
   rails2.3.11
   todo2

用途

为什么要用rvm来进行ruby和gem的配置?

可以举出一些例子来说明rvm实际可以应用的场景。

例如:机器上需要开启一个服务,它需求ruby某版本,但是并不希望将此机器上的ruby版本升级或者降级。即:需求希望有一个隔离原系统环境的ruby环境来提供服务。

再例如:一台机器上需要搭载多个服务,但这几个服务需求不同的gems,在需求的gem包上会有冲突;更麻烦的情况还有:不同服务需求不同的ruby版本!

这些问题都可以用rvm进行解决。

部署rvm(无论是上述哪个方式,都是可以接受的),利用rvm use ....命令,就可以进行快速的ruby和gemset的切换,这就满足了多ruby和多gem包配置的需求(具体的业务方案,rvm很灵活,显然可以自由配置了)。而如果不希望使用rvm的ruby,可以直接敲这个:

rvm use system --default

这样,此用户就默认使用系统的ruby,而忽略rvm了。

后序

而在自建ruby应用的部署上,显然很简单了:

  1. 自建gems server ;
  2. 根据需求,如上述的 直接复制部署 rvm 章节描述的部署方式,打包rvm之时同时包含了初始化的ruby和gems,同时更新了应当更新的配置内容(如需要把默认的gem source更新为自建gems server的地址、config/db的binary url更新为自建的ruby二进制提供地址)
  3. 初始化部署即如上述执行,是可以做到在几条命令中,快速部署了rvm(同时配置了多个ruby和多个gems,如现在的多个版本的puppet应用的需求,即如此完成)
  4. 利用rvm更新的需求应该就两种:更新gem,更新ruby。更新gem利用自建的gems server,更新ruby利用自建的server 提供 ruby binary url(其实如果部署使用ruby 1.9.3,应该一两年内都不会去更新ruby)。

【完】

2013.04.07, ottocho


Til next time,
at 20:12

scribble

Home About GitHub