ruby on rails 学习笔记(二)

Ruby 对 Windows 的支持不太好,主要是使用了 C/C++ 代码的 Gem 对 Windows 支持不好, 在 Windows 下安装这些 Gem 时,能在当前计算机上正确编译这些 C/C++ 代码是一件艰难的事。 所以在 Windows 下开发 Rails 是一件很折腾人的事。 但是如果工作环境限定了要使用 Windows,可以用虚拟机的方式。简单来说就是在 Windows 上安装 虚拟机软件,在虚拟机安装 Linux,使用这个 Linux 来作为 Rails 的开发环境。 而 Vagrant 是让使用这个虚拟机环境更加方便的工具。

在 Win7 下安装配置 Vagrant 作为 Rails 开发环境

以下对ruby on rails 环境搭建,基于windows7 64位操作系统,使用virtualbox下ubuntu虚拟机。

问题1-获取virtualbox com 对象失败 Failed to instantiate CLSID_VirtualBox

错误详情:VirtualBox无法打开,打开后提示创建COM对象失败;被召者 RC:E_NOINTERFACE (0x80004002)。SAQ后发现需要修改VirtualBox 属性里兼容性(除去win7)和权限(管理员权限),但是并没有作用,后来又查到在BIOS中修改CPU设置,打开Intel VT功能,保存并退出。发现以前装vmwarm时已经改了,不管怎样改了在之后保持,再打开又可以了,奇怪的机器语言!!!

问题2-VirtualBox兼容性

1
2
3
4
5
6
7
8
9
10
11
12
C:\Users\Administrator>e:
E:\HashiCorp\Vagrant\work\rails>vagrant init
E:\HashiCorp\Vagrant\work\rails>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["list", "hostonlyifs"]
Stderr: VBoxManage.exe: error: Failed to create the VirtualBox object!
VBoxManage.exe: error: Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but CLSID_VirtualBox w/ IUnknown works.
VBoxManage.exe: error: PSDispatch looks fine. Weird
VBoxManage.exe: error: Details: code E_INVALIDARG (0x80070057), component VirtualBoxClientWrap, interface IVirtualBoxClient
E:\HashiCorp\Vagrant\work\rails>

在VirtualBox安装目录中找到VBoxManage.exe,右击选择属性,设置Windows Server 2008兼容模式运行。再执行vagrant up,正常运行

问题3-VBoxManage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
E:\>cd E:\HashiCorp\Vagrant\work\rails
E:\HashiCorp\Vagrant\work\rails>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'base'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: rails_default_1479003001297_34537
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 80 (guest) => 8080 (host) (adapter 1)
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["startvm", "ba7b2954-6c95-4cea-bca4-a67b7e70b2cb", "--type", "headless"]
Stderr: VBoxManage.exe: error: The virtual machine 'rails_default_1479003001297_34537' has terminated unexpectedly during startup with exit code 1 (0x1). More details may be a
vailable in 'C:\Users\Administrator\VirtualBox VMs\rails_default_1479003001297_34537\Logs\VBoxHardening.log'
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component MachineWrap, interface IMachine

查找问题发现只有英文讨论,也只好硬着头皮看

1
2
3
4
5
6
7
8
9
10
11
12
13
获取 VirtualBox COM 对象失败.
应用程序将被中断.
Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but CLSID_VirtualBox w/ IUnknown works.
PSDispatch looks fine. Weird.
返回 代码:E_INVALIDARG (0x80070057)
组件:VirtualBoxClientWrap
界面:IVirtualBoxClient {d2937a8e-cb8d-4382-90ba-b7da78a74573}

发现问题应该出在VirtualBox上,就查阅VirtualBox贴吧,发现win7-64同样的问题很多

用4.3.12版本就可以了。我win7 64位之前用的5.0.14,开始没问题过了几天后也报 rc=-104错误。
试过以下方法:
1、“如D:\Program Files\Oracle\VirtualBox\drivers\vboxdrv,
右击VBoxDrv.inf,选安装,然后重启。”
2、目录用默认的C盘
3、卸载重装
这3种方法都没用。
最后改成4.3.12版本后就ok了

改用VirtualBox4.3.12后问题解决,想了想终究归于兼容性问题吧

问题4- Ubuntu 源修改为网易源

wget http://mirrors.163.com/.help/sources.list.trusty 命令无效

解决方法ubuntu : sudo apt-get install wget 安装wget命令应用

问题5-ssh executable not found in any directories in the %PATH%

1
2
3
4
5
6
7
8
9
10
c:\Users\dhawal.vora>vagrant ssh
`ssh` executable not found in any directories in the %PATH% variable. Is an
SSH client installed? Try installing Cygwin, MinGW or Git, all of which
contain an SSH client. Or use your favorite SSH client with the following
authentication information shown below:
Host: 127.0.0.1
Port: 2222
Username: vagrant
Private key: c:/Users/dhawal.vora/.vagrant/machines/default/virtualbox/private_key

SSH 连接到虚拟机,Windows 用 Putty 去连接
参考windows下使用ssh挫折记录
尝试开启控制面板\用户帐户和家庭安全\用户帐户\管理帐户

1
ssh_exchange_identification: read: Connection reset by peer

重启然后vagrant up后出现以下问题

1
2
3
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

解决方法有两种说法一种是修改configfile里 vb.gui = true,另一种勾选virtualbox管理器/设置/网络/接入网线。之后重启问题解决

1
2
3
4
5
6
E:\HashiCorp\Vagrant\work\rails>vagrant ssh
Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.13.0-24-generic x86_64)
* Documentation: https://help.ubuntu.com/
Last login: Mon Nov 14 13:03:39 2016
vagrant@vagrant-ubuntu-trusty:~$

问题6-localhost:8080打不开

打不开的原因自我分析出在rails server上,同时发现问题出在环境搭建上,同时也可能是映射问题,所以准备从头开始一步一步,慢工出细活,也是更好的学习环境搭配。

从头开始

软件准备

VirtualBox-4.3.12-93733-Winubuntu 14.04 X64agrant_1.8.7github

VirtualBox选择4.3.12版本因为在window版本下表现更为稳定,而虚拟机模板镜像box选取的是纯净版的ubuntu,原由在于自带的很多内容已经过时,还是得自己装,而且有一些预先的设置并没有写清楚,造成查找问题比较耗时间,ubuntu 14.04 X64取自在 Win7 下安装配置 Vagrant 作为 Rails 开发环境

环境变量 path

同样的,也要将virtualBox的目录路径(类似于C:\Program Files\Oracle\VirtualBox)添加到环境变量path中
提醒一下,如果忘了添加路径到path,在后面步骤中出现问题,再来添加路径后,一定要重新打开命令端,让命令端重新载入环境变量才能生效。

添加一个虚拟机模板

初始化虚拟机

先选定一个虚拟机目录,在这个目录中,会存放这个虚拟机的 Vagrant 配置文件, 后面启动虚拟机时,需要先切换到这个下来

1
2
3
cd E:\HashiCorp\Vagrant\work\rails
vagrant init
vagrant up

ruby on rails安装必要的软件及包

安装curl-sudo apt-get install curl

安装rvm-需要到官网复制两条命令行如下:

1
2
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable

更改rvm源服务器资源信息,毕竟国外的经常被墙掉,还有就是国内的速度快。若不设置,下面可能出现各种问题,如出现服务器积极拒绝(被墙),或者下载速度慢
$ sed -i -e ‘s/ftp.ruby-lang.org\/pub\/ruby/ruby.taobao.org\/mirrors\/ruby/g’ ~/.rvm/config/db

安装ruby-rvm install 2.2.0

1
apt-get install -y build-essential openssl curl libcurl3-dev libreadline6 libreadline6-dev git zlib1g zlib1g-dev libssl-dev libyaml-dev libxml2-dev libxslt-dev autoconf automake libtool imagemagick libmagickwand-dev libpcre3-dev libsqlite3-dev

安装ruby-rvm install ruby

切换到淘宝服务器 gem

1
2
3
4
gem source
gem source -r https://rubygems.org/
//添加淘宝源,
gem source -a https://ruby.taobao.org

使用gem安装rails-gem install rails

创建rails工程

rails new blog –skip-bundle
cd blog
bundle install

安装js编译器

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
若不安装,本机有没有js编译器,直接执行rails server,则会报错:
ubuntu:~/app/rails/blog$ rails server
//Could not find a JavaScript runtime

启动server-rails server

vagrant@vagrant-ubuntu-trusty:~/app/rails/blog$ rails server
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run rails server -h for more startup options
Puma starting in single mode…

  • Version 3.6.0 (ruby 2.3.2-p217), codename: Sleepy Sunday Serenity
  • Min threads: 5, max threads: 5
  • Environment: development
  • Listening on tcp://localhost:3000
    Use Ctrl-C to stop

编辑 Vagrantfile 文件

一般情况下,进行开发时,源代码保存在宿主机中,方便地使用 IDE 等工具, 虚拟机环境一般只用来运行代码,所以这里就需要使用目录映射功能,将本地的目录映射到虚拟机的对应目录。

config.vm.provider "virtualbox" do |vb|
Display the VirtualBox GUI when booting the machine
vb.gui = true
vb.cpus = 2 Customize the amount of cpu on the VM:
Customize the amount of memory on the VM:
vb.memory = "1024"
end
config.vm.network "forwarded_port", guest: 3000, host: 3000

不能设置共享文件夹的问题的解决

在宿主机中运行 VirtualBox.exe,在 VirtualBox 管理器中看到正在运行的虚拟机。 给这个虚拟机设置虚拟光盘为 VBoxGuestAdditions.iso 文件。VBoxGuestAdditions.iso 文件 在 VirtualBox 的安装目录下。

1
2
3
4
5
sudo mount /dev/cdrom /media/cdrom
cd /media/cdrom
sudo ./VBoxLinuxAdditions.run # 安装
sudo umount /media/cdrom
sudo eject /dev/cdrom

mount 需要root权限,root 密码修改sudo passwd,最后重启vagrant reload

iptables防火墙规则

1
2
3
sudo iptables -I INPUT -p tcp --dport 3000 -j ACCEPT
sudo iptables -I OUTPUT -p tcp --sport 3000 -j ACCEPT
iptables-save

虚拟机根目录下

localhost:3000

打开时一直有问题,后来发现要rails server -b 0.0.0.0方式启动服务

原因:Port 3000 in the host computer is forwarded to port 3000 in the virtual machine. Thus, applications running in the virtual machine can be accessed via localhost:3000 in the host computer. Be sure the web server is bound to the IP 0.0.0.0, instead of 127.0.0.1, so it can access all interfaces:

vagrant up,启动
vagrant halt,停止
vagrant suspend,暂时挂起,将虚拟机的状态保存在磁盘上,可以用 vagrant up 或 vagrant resume,重新启动起来,会比停止之后再启动速度快。
vagrant status,查看虚拟机状态
vagrant destroy,销毁虚拟机,一切都没有了,除了虚拟机模板,小心使用
vagrant package,打包当前虚拟机为 box
在虚拟机中使用 sudo reboot 重启,目录映射不起作用,使用 vagrant reload 才行

参考文献