ror-tutorial-v2-notes

安装ruby和rails

ruby生态系统中有两个并列的工具,rbenv和rvm,主要用来进行环境变量的隔离。在教材中,使用的是rvm,但在rails的官方页面中,推荐使用的是rbenv。因此这里我也使用rbenv.

参考:http://rubyonrails.org/download/

1. 安装rbenv

[fangpeng@vps1 ~]$ cd /home/fangpeng/
[fangpeng@vps1 ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
[fangpeng@vps1 ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
[fangpeng@vps1 ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

重新打开一个ssh会话,使得上面设置的环境变量生效。 检查rbenv是否安装成功:

[fangpeng@vps1 ~]$ type rbenv
rbenv is a function
rbenv () 
{ 
    local command;
    command="$1";
    if [ "$#" -gt 0 ]; then
        shift;
    fi;
    case "$command" in 
        rehash | shell)
            eval "`rbenv "sh-$command" "$@"`"
        ;;
        *)
            command rbenv "$command" "$@"
        ;;
    esac
}

至此,rbenv安装成功。

2. 安装ruby-build

ruby-build is an rbenv plugin that provides an rbenv install command to compile and install different versions of Ruby on UNIX-like systems.

[fangpeng@vps1 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

3. 安装ruby

查看可以安装的ruby版本:

[fangpeng@vps1 ~]$ rbenv install -l

选择安装最新的稳定版2.2.1

[fangpeng@vps1 ~]$ rbenv install 2.2.1

结果报错如下:

[fangpeng@vps1 ~]$ rbenv install 2.2.1
Downloading ruby-2.2.1.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/5a4de38068eca8919cb087d338c0c2e3d72c9382c804fb27ab746e6c7819ab28
Installing ruby-2.2.1...

BUILD FAILED (CentOS 7.1.1503 using ruby-build 20150319zf)

Inspect or clean up the working tree at /tmp/ruby-build.20150405121040.8031
Results logged to /tmp/ruby-build.20150405121040.8031.log

Last 10 log lines:
collect2: error: ld returned 1 exit status
make[2]: *** [../../.ext/x86_64-linux/fiddle.so] Error 1
make[2]: Leaving directory `/tmp/ruby-build.20150405121040.8031/ruby-2.2.1/ext/fiddle'
make[1]: *** [ext/fiddle/all] Error 2
make[1]: *** Waiting for unfinished jobs....
installing default nkf libraries
linking shared-object nkf.so
make[2]: Leaving directory `/tmp/ruby-build.20150405121040.8031/ruby-2.2.1/ext/nkf'
make[1]: Leaving directory `/tmp/ruby-build.20150405121040.8031/ruby-2.2.1'
make: *** [build-ext] Error 2

查看安装日志,发现具体的错误信息为:

/usr/bin/ld: ./libffi-3.2.1/.libs/libffi.a(raw_api.o): relocation R_X86_64_32S against `.rodata' can not be used when mak
ing a shared object; recompile with -fPIC
./libffi-3.2.1/.libs/libffi.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status

安装libffi-devel:

[root@vps1 ~]# yum install libffi-devel

再次安装ruby:

[fangpeng@vps1 ~]$ rbenv install 2.2.1

安装成功。

4. 设置ruby版本

在/home/fangpeng目录下执行:

[fangpeng@vps1 ~]$ cd /home/fangpeng/
[fangpeng@vps1 ~]$ rbenv local 2.2.1

此命令的效果是在当前目录生成了一个.ruby-version文件,并且,在该目录及其子目录中,ruby默认使用指定的版本。具体参考rbenv的github页面。总之,作用就是达到环境的隔离,可以实现在一个目录下ruby默认使用A版本,但在另一个目录下默认使用B版本。

5. 安装rails

安装最新的rails版本:

[fangpeng@vps1 ~]$ gem install rails

安装的过程,发现在安装到ri documentation的时候特别卡,cpu占用率100%. 这个问题出现很久了,见: https://github.com/rails/rails/issues/11814

因此,很多人建议不安装rdoc:

gem install rails --no-ri --no-rdoc

我这里还是等到rdoc安装完毕。 至此,最新版ruby和rails均已安装完毕。rails的版本为4.2.1

[fangpeng@vps1 ~]$ rails -v
Rails 4.2.1

6. 测试rails

[fangpeng@vps1 project]$ cd /home/fangpeng/project/
[fangpeng@vps1 project]$ rails new helloworld

结果报错:

[fangpeng@vps1 project]$ rails new helloworld
      create  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/assets/images/.keep
      create  app/mailers/.keep
      create  app/models/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/bundle
      create  bin/rails
      create  bin/rake
      create  bin/setup
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/secrets.yml
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/assets.rb
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookies_serializer.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  lib/assets
      create  lib/assets/.keep
      create  log
      create  log/.keep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/robots.txt
      create  test/fixtures
      create  test/fixtures/.keep
      create  test/controllers
      create  test/controllers/.keep
      create  test/mailers
      create  test/mailers/.keep
      create  test/models
      create  test/models/.keep
      create  test/helpers
      create  test/helpers/.keep
      create  test/integration
      create  test/integration/.keep
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
         run  bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 10.4.2
Using i18n 0.7.0
Installing json 1.8.2
Installing minitest 5.5.1
Using thread_safe 0.3.5
Using tzinfo 1.2.2
Using activesupport 4.2.1
Using builder 3.2.2
Using erubis 2.7.0
Using mini_portile 0.6.2
Using nokogiri 1.6.6.2
Using rails-deprecated_sanitizer 1.0.3
Using rails-dom-testing 1.0.6
Using loofah 2.0.1
Using rails-html-sanitizer 1.0.2
Using actionview 4.2.1
Using rack 1.6.0
Using rack-test 0.6.3
Using actionpack 4.2.1
Using globalid 0.3.3
Using activejob 4.2.1
Using mime-types 2.4.3
Using mail 2.6.3
Using actionmailer 4.2.1
Using activemodel 4.2.1
Using arel 6.0.0
Using activerecord 4.2.1
Installing debug_inspector 0.0.2
Installing binding_of_caller 0.7.2
Using bundler 1.9.2
Installing columnize 0.9.0
Installing byebug 4.0.5
Installing coffee-script-source 1.9.1
Installing execjs 2.4.0
Installing coffee-script 2.3.0
Using thor 0.19.1
Using railties 4.2.1
Installing coffee-rails 4.1.0
Using hike 1.2.3
Using multi_json 1.11.0
Installing jbuilder 2.2.12
Installing jquery-rails 4.0.3
Using tilt 1.4.1
Using sprockets 2.12.3
Using sprockets-rails 2.2.4
Using rails 4.2.1
Using rdoc 4.2.0
Installing sass 3.4.13
Installing sass-rails 5.0.3
Installing sdoc 0.4.1
Installing spring 1.3.3

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /home/fangpeng/.rbenv/versions/2.2.1/bin/ruby -r ./siteconf20150405-31514-7mpjub.rb extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/home/fangpeng/.rbenv/versions/2.2.1/bin/$(RUBY_BASE_NAME)
    --with-sqlite3-dir
    --without-sqlite3-dir
    --with-sqlite3-include
    --without-sqlite3-include=${sqlite3-dir}/include
    --with-sqlite3-lib
    --without-sqlite3-lib=${sqlite3-dir}/lib

extconf failed, exit code 1

Gem files will remain installed in /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sqlite3-1.3.10 for inspection.
Results logged to /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0-static/sqlite3-1.3.10/gem_make.out
An error occurred while installing sqlite3 (1.3.10), and Bundler cannot continue.
Make sure that `gem install sqlite3 -v '1.3.10'` succeeds before bundling.
         run  bundle exec spring binstub --all
/home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/resolver.rb:333:in `block in verify_gemfile_dependencies_are_found!': Could not find gem 'sqlite3 (>= 0) ruby' in the gems available on this machine. (Bundler::GemNotFound)
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/resolver.rb:307:in `each'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/resolver.rb:307:in `verify_gemfile_dependencies_are_found!'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/resolver.rb:199:in `start'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/resolver.rb:182:in `resolve'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/definition.rb:193:in `resolve'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/definition.rb:132:in `specs'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/definition.rb:177:in `specs_for'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/definition.rb:166:in `requested_specs'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/environment.rb:18:in `requested_specs'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:13:in `setup'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler.rb:122:in `setup'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/setup.rb:18:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'

原因是没有安装sqlite3,安装如下:

[root@vps1 ~]# yum install sqlite-devel

进入刚才新建的helloworld目录,继续安装,执行:

[fangpeng@vps1 helloworld]$ bundle install

安装成功!

在helloworld目录里启动rails服务:

[fangpeng@vps1 helloworld]$ rails server

结果报错如下:

[fangpeng@vps1 helloworld]$ rails server
    Sorry, you can't use byebug without Readline. To solve this, you need to
    rebuild Ruby with Readline support. If using Ubuntu, try `sudo apt-get
    install libreadline-dev` and then reinstall your Ruby.
/home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/history.rb:2:in `require': cannot load such file -- readline (LoadError)
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/history.rb:2:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/interface.rb:1:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/interface.rb:1:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/core.rb:5:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug/core.rb:5:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug.rb:1:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/byebug-4.0.5/lib/byebug.rb:1:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:76:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:72:in `each'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:72:in `block in require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:61:in `each'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler/runtime.rb:61:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/bundler-1.9.2/lib/bundler.rb:134:in `require'
    from /home/fangpeng/project/helloworld/config/application.rb:7:in `<top (required)>'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:78:in `require'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:78:in `block in server'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:75:in `tap'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:75:in `server'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /home/fangpeng/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

于是安装readline-devel:

[root@vps1 ~]# yum install readline-devel

并重新安装ruby:

[fangpeng@vps1 ~]$ rbenv install 2.2.1

安装成功后,再次在helloworld目录开启rails server:

[fangpeng@vps1 helloworld]$ rails server

此时,rails server成功启动,通过浏览器访问:http://103.251.90.250 无反应。此时需要修改两个地方.

第一,关闭本机防火墙:

systemctl stop firewalld

当然,这里只是本笔记用的开发环境,如果是生产环境,肯定不应该将防火墙关掉。

第二,启动rails server时需要绑定公网IP:

[fangpeng@vps1 helloworld]$ rails server -b xx.xx.xx.xx -d

其中xx.xx.xx.xx为本VPS的公网IP.-d参数为使得rails server在后台运行。

此时,rails server成功启动,并且通过浏览器访问http://xx.xx.xx.xx:3000可以看到rails默认的欢迎页面:

7. 将配置nginx反向代理到rails server

迄今为止,rails server只能通过外网IP和3000端口来访问。而为了能通过域名rails.pureage.info访问到xx.xx.xx.xx:300,我们在nginx中配置好反向代理:

        location / {
            proxy_pass http://127.0.0.1:3000;
            root   html;
            index  index.html index.htm;
        }

reload nginx:

[root@vps1 conf]# /usr/local/openresty/nginx/sbin/nginx -s reload

此时,由于是通过nginx走的反向代理,所以rails server可以不用绑定外网IP,直接在helloworld目录执行:

[fangpeng@vps1 helloworld]$ rails server -d

即可。现在,通过浏览器访问http://rails.pureage.info,即可访问到rails了。