Running startup shell script for ruby application as other user (not root)

n3rve asked:

I have installed RVM using ‘user01’ on Ubuntu 14.04 and user01 can start my rails application as expected. I, however, want to start this application following system start-up. I am trying to use the following to achieve this:


screen -d -m mongrel_rails start -e production -p 8088

/etc/rc.local (added before exit 0)

sh './var/script/'

Using the changes above, my rails application fails to start. I can confirm this because there is no active GNU screen session (the screen -d -m mongrel_rails… command starts a screen session and detaches. I should be able to see the session with the “screen -ls” command, but I don’t, even after switching to root).

I switched to root (sudo su) and attempted to manually start the application but it failed with the following:

/usr/bin/env: ruby: No such file or directory

I figured that RVM/Ruby is broken for root. I confirmed this by running ‘ruby -v’ which returned a message confirming that the application was not installed. This isn’t the case for user01 who sees information about the ruby version installed.

I continued to find a way around this and found this post that suggested the following command to switch to the user while executing the start-up command.

su user01 -c '/var/script/'

This didn’t help as well and after investigating, I found that ruby was broken for user01 when I ‘su user01’ into this account from root. ‘ruby -v’ failed to return the expected information as well. After testing manually, I found that typing ‘exit’ returned me to root, and another ‘exit’ returned me to user01 (the account I used to login) and ruby works properly for this account.

Can anyone suggest a way to get around this?

My answer:

You’re using rvm, so the proper way to deal with ruby not being found is to use an rvm wrapper (on SysVinit and upstart systems).

First (optional) create an alias for your app to the gemset you want to use:

rvm alias create my_app ruby-2.1.4@my_gemset

Then create the wrapper(s) you want:

rvm wrapper my_app mongrel_rails

The wrapper is created in the $rvm_path/wrappers/my_app directory, and then you call it from your init script after switching users.

su user01 -c '/home/user01/.rvm/wrappers/my_app/mongrel_rails -e production -p 8088'

(Note that I’ve completely removed screen from this, as there’s little good reason to be running this within a screen.)

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.