开发者

How does RVM work in production with no users logged in?

开发者 https://www.devze.com 2023-03-03 20:39 出处:网络
Considering putting RVM into production (light duty) on a new machine. But I\'m not visualizing how it will work if a user isn\'t logged in. RVM has been installed into /usr/local/rvm/bin/rvm so it is

Considering putting RVM into production (light duty) on a new machine. But I'm not visualizing how it will work if a user isn't logged in. RVM has been installed into /usr/local/rvm/bin/rvm so it is available to "everyone".

If server restarts and is at login screen and background daemons are serving apache/rails, etc. and no .bashrc, etc. have loaded...how/where do we specify which of RVM's Rubies to load?

Perhaps somewhere in Phusion's Passenger?

开发者_StackOverflow

who manages these gemsets? are they shared?


You can use RVM's wrapper command to generate scripts that load up the correct RVM environment before executing the necessary binaries. The format is:

rvm wrapper [ruby_string] [wrapper_prefix] [binary[ binary[ ...]]]

For example, to create a binary named system_unicorn that loads ruby-1.9.2-p180 and then executes unicorn, use the following:

rvm wrapper ruby-1.9.2-p180 system unicorn

You can pass multiple binaries to create wrappers for. For example, to create wrappers for both unicorn and god, run

rvm wrapper ruby-1.9.2-p180 system unicorn god

ruby_string can be anything you can pass to rvm use, and thus can contain gemsets as well; for example, to create myapp_unicorn for the gemset my_app_gemset, use:

rvm wrapper ruby-1.9.2-p180@my_app_gemset myapp unicorn

When you install Passenger these days, it automatically creates a wrapper for it's ruby (pretty sure it calls it passenger_ruby) that loads up the correct version of Ruby (the one you're using when you install it). You can use config/setup_load_paths.rb to specify a gemset--see this Stack Overflow answer.


I've dealt with this in the past by running all jobs with a user that has rvm set up. It does add complexity to many simple jobs because you have to make sure that rvm is loaded. If you need to run commands as root AND use rvm, you can use the rvmsudo command.

You can also install RVM systemwide as root:

  • https://rvm.beginrescueend.com/rvm/install/


1) root installs the ruby versions and gems under RVM if you install them globally (read the RVM readme -- there seem to be possible problems when installing globally!)

2) if you're on UNIX, each of your system processes gets started as a particular user, e.g. on LINUX through the init-scripts in /etc/init.d/ ... while the processes are created as a particular user, the mapping of user names to UID/GID, the home directory, and login-shell are looked up in the /etc/passwd file -- that is where the login shell (e.g. bash) is defined for a particular user.

So, coming back to your statement:

If server restarts and is at login screen and background daemons are serving apache/rails, etc. 
and no .bashrc, etc. have loaded...how/where do we specify which of RVM's Rubies to load?

You see the problem with that statement?

When the server starts, and the background processes are started, each of them gets started as a particular user, with a particular login shell and with a particular home directory.

RVM will need that you have your login shell set to /bin/bash -- otherwise it couldn't set up the RVM environment for any of the processes that are run by that particular user. e.g. RVM will not work if you use /bin/nologin as the default shell.

Problem1: That's a security problem of course! In general, daemons should not have a shell set for security reasons.

Problem2: You don't want to make high-powered tools available to somebody breaking into your server - that's why you shouldn't have cc and other tools on a production server - that's why you should not compile your Rubys and Gems on the production server, but rather copy the .rvm directory onto the production servers...

Problem3: (more general) The way RVM manages all it's Ruby and Gem versions is very very kludgy approach to version management.. Using special features of one particular login shell to facilitate the version management is not a good idea IMHO - sure there is nothing better at the moment, but in the old days, the idea behind Lude was a far better approach to install different versions of software: http://www.iro.umontreal.ca/contrib/lude/lude2_toc.html

Conclusion:

So as I mentioned in a previous post, I highly recommend to set up RVM a normal user account to run your Ruby and Rails processes and to set up that one account with /bin/bash as the login shell and to copy your .rvm directory from your dev-server to your production machines via scp or rsync -- it's the better and safer approach.


I had a similar problem, where I want to deploy the ruby version and all associated gems to the production machines...

Because of the reasons outlined in my other post, I chose to go with a local RVM install. I have a user "deploy" on both my dev-servers and my production servers.

I would highly recommend that you use either "rsync' or 'scp -rp' to copy the complete subdirectory ~/.rvm to the target machine (remember that you don't want to have cc and other tools on a production server!)

One important Gotcha:

be sure that you use the identically named user account on all machines, if you replicate the .rvm directory!

I noticed that the internal book-keeping of RVM keeps track of some environment variables during installation of Ruby versions and gems, and that it keeps track in particular of the name of the user account that was used, and the path to the users's home directory. Beats me why they don't use $HOME and $USER , which are standard on all UNIXes.. seems like a real bug in RVM to me.

if you use the same user account for all machines, it will work just fine.

e.g. I use a user "deploy" which has the .rvm directory and which owns the running processes.

UPDATE

if you use rsync or scp to sync your deployment account, the downside is that you need to restart your servers, e.g. unicorn, manually.

Another promising way of deploying RVM and Rails apps is to deploy to one machine, where bundle update is run, and then create an RPM out of the whole deployment account, which is then installed via rpm -Uhv or a private yum repository onto all the nodes. Advantage here is that the services on the nodes can be easily restarted via a %post action in the RPM.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号