在 Ubuntu 上将 rbenv 的 ruby 作为系统 ruby(启动时使用 rbenv 的 ruby)
Making rbenv's ruby as system ruby (Using rbenv's ruby when start up) on Ubuntu
我正在尝试在 Ubuntu 启动时启动 rails 应用程序。
为此,我在 /etc/rc.local
中添加了这些行。
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
bundle exec passenger start --port 8000 --user ubuntu --daemonize
然而,rc.local
退出并出现错误
+ cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
+ bundle exec passenger start --port 8000 --user ubuntu --daemonize
/usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:92:in `block in materialize': Could not find rake-10.4.2 in any of the sources (Bundler::GemNotFound)
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `map!'
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `materialize'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:114:in `specs'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:159:in `specs_for'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:148:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/environment.rb:18:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/runtime.rb:13:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler.rb:120:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler/setup.rb:17:in `<top (required)>'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
错误是使用rbenv安装的ruby引起的; ruby 在 /home/ubuntu/.rbenv/bin/ 目录中。我猜当 ubuntu 启动时,系统 ruby 被执行,但它不知道任何关于 rbenv 的 ruby 和 gem 的安装包。
我该如何解决这个问题?有什么方法可以使 rbenv 中的 ruby 成为系统的 ruby?
为了得到错误,我使用了这个post的提示:Run script with rc.local: script works, but not at boot。
编辑
mwp 的回答很好,但我想我最好把事情说清楚。
开发包
运行 bundle --deployment --binstubs
创建 ./vendor 并在 bundle 目录中复制文件。
setup.sh
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/home/ubuntu/.rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
$APP_ROOT/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
rc.local 文件
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
sh ./setup.sh
exit 0
运行 这些命令一次:
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
rbenv local <the version you want>
这将在您的应用程序目录中创建一个 .ruby-version
文件,告诉 rbenv 使用哪个版本。
我还建议在将应用程序部署到其 "production" 位置时,使用 --deployment --binstubs
标志安装捆绑程序。这将在 vendor
子目录中安装 Gems(将它们与错误的 Gem 更新隔离)并在 bin
子目录中创建方便的快捷方式到 运行例如passenger
、rackup
等,无需执行 bundle exec
。
但是,您还有另一个问题,那就是 rbenv
(shell 函数)[可能] 不可用,而 rc.local
是 运行ning .我会建议创建一个新的 shell 脚本并将其存储在某个地方,可能在您的应用程序的目录结构中,具有(类似于)以下内容:
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/path/to/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
"$APP_ROOT"/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
然后将此脚本标记为可执行,您可以从 rc.local 调用它来启动服务。至于你设置 RBENV_ROOT
的内容,你可以使用现有用户的 .rbenv
目录(例如 ~ubuntu/.rbenv
,假设你在那里安装了一个副本),或者你可以设置一个系统 - /opt/rbenv
或其他地方的宽 rbenv。有一些不错的笔记here.
我可以想出一百万种不同的方法来改进上述脚本,实际上这只是解决这个问题的一百万种不同方法中的一种。启动和停止服务是目前 DevOps 和系统管理员社区中的一个热门话题。我使用 rbenv 和 Bundler 在生产中 运行ning Ruby 应用程序取得了巨大的成功,如果你决定走这条路,我希望你也能!
Upstart (http://upstart.ubuntu.com) 可能是替代 rc.local 的更好方法。
# simple script
# http://uwsgi-docs.readthedocs.org/en/latest/Upstart.html
description "passenger "
start on runlevel [2345]
stop on runlevel [06]
respawn
#
script
chdir /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
exec sh runme.sh
end script
我正在尝试在 Ubuntu 启动时启动 rails 应用程序。
为此,我在 /etc/rc.local
中添加了这些行。
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
bundle exec passenger start --port 8000 --user ubuntu --daemonize
然而,rc.local
退出并出现错误
+ cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
+ bundle exec passenger start --port 8000 --user ubuntu --daemonize
/usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:92:in `block in materialize': Could not find rake-10.4.2 in any of the sources (Bundler::GemNotFound)
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `map!'
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `materialize'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:114:in `specs'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:159:in `specs_for'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:148:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/environment.rb:18:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/runtime.rb:13:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler.rb:120:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler/setup.rb:17:in `<top (required)>'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
错误是使用rbenv安装的ruby引起的; ruby 在 /home/ubuntu/.rbenv/bin/ 目录中。我猜当 ubuntu 启动时,系统 ruby 被执行,但它不知道任何关于 rbenv 的 ruby 和 gem 的安装包。
我该如何解决这个问题?有什么方法可以使 rbenv 中的 ruby 成为系统的 ruby?
为了得到错误,我使用了这个post的提示:Run script with rc.local: script works, but not at boot。
编辑
mwp 的回答很好,但我想我最好把事情说清楚。
开发包
运行 bundle --deployment --binstubs
创建 ./vendor 并在 bundle 目录中复制文件。
setup.sh
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/home/ubuntu/.rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
$APP_ROOT/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
rc.local 文件
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
sh ./setup.sh
exit 0
运行 这些命令一次:
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
rbenv local <the version you want>
这将在您的应用程序目录中创建一个 .ruby-version
文件,告诉 rbenv 使用哪个版本。
我还建议在将应用程序部署到其 "production" 位置时,使用 --deployment --binstubs
标志安装捆绑程序。这将在 vendor
子目录中安装 Gems(将它们与错误的 Gem 更新隔离)并在 bin
子目录中创建方便的快捷方式到 运行例如passenger
、rackup
等,无需执行 bundle exec
。
但是,您还有另一个问题,那就是 rbenv
(shell 函数)[可能] 不可用,而 rc.local
是 运行ning .我会建议创建一个新的 shell 脚本并将其存储在某个地方,可能在您的应用程序的目录结构中,具有(类似于)以下内容:
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/path/to/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
"$APP_ROOT"/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
然后将此脚本标记为可执行,您可以从 rc.local 调用它来启动服务。至于你设置 RBENV_ROOT
的内容,你可以使用现有用户的 .rbenv
目录(例如 ~ubuntu/.rbenv
,假设你在那里安装了一个副本),或者你可以设置一个系统 - /opt/rbenv
或其他地方的宽 rbenv。有一些不错的笔记here.
我可以想出一百万种不同的方法来改进上述脚本,实际上这只是解决这个问题的一百万种不同方法中的一种。启动和停止服务是目前 DevOps 和系统管理员社区中的一个热门话题。我使用 rbenv 和 Bundler 在生产中 运行ning Ruby 应用程序取得了巨大的成功,如果你决定走这条路,我希望你也能!
Upstart (http://upstart.ubuntu.com) 可能是替代 rc.local 的更好方法。
# simple script
# http://uwsgi-docs.readthedocs.org/en/latest/Upstart.html
description "passenger "
start on runlevel [2345]
stop on runlevel [06]
respawn
#
script
chdir /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
exec sh runme.sh
end script