I was playing around with bundler and noticed a warning when running bundle install with root privileges:
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this application for all non-root users on this machine.
Why is that?
There are two things which interact with each other to make installing most software as root a "bad idea":
Most programs which create files default to creating them as the user who ran the program.
Files created by root typically don't give anyone else read/write/execute permissions.
In the case of installing packages as root with Bundler, this means that the scripts in the ruby gem you install would not be accessible to any other users.
Related
I've recently started having an issue installing any Ruby gem or node modules on my local dev environment when it comes to installing anything via the terminal. It was working normally for some time.
sudo gem install compass
This appears to install correctly however when i run
compass -v
I get
/usr/bin/compass: Permission denied
When I browse to /usr/bin/compass and "Get Info" on compass it says system - Read & Write, everyone - No Access as opposed to everyone - read only or...
-rwx------ 1 root wheel 512 Jul 27 14:46 compass
For some reason everything is getting written with incorrect permissions.
Same goes for Node.js modules.
sudo npm install gulp
Appears to work but I get the same permissions issue when I try to use it
/usr/local/bin/gulp: Permission denied
I've exhausted my search and hope someone can help provide some insight on how I can permanently fix this issue
This is happening because you're installing gems with sudo and, as such, root is taking possession of everything. So, instead of using sudo I'd advise using RVM. RVM provides you with an easy way to manage multiple versions of Ruby, each of which gets their own home for gems in ~/.rvm which avoids the permission difficulties you're experiencing. Additionally, it's possible (but not recommended) to do a global RVM install that works for all users.
EDIT: As the Tin Man mentioned in response to me, a global RVM install is not only not recommended in a general sense, but the RVM authors themselves advise against it. Caveat emptor and such. You should find the single-user version more than adequate in any case, though.
If you run ruby bundler from the command line while logged in as root, you get the following warning:
Don't run Bundler as root. Bundler can ask for sudo if it is needed,
and installing your bundle as root will break this application for all
non-root users on this machine.
What is this exact difference that running bundler as root makes to the gems it installs?
Is it to do with the permissions of the actual files that it installs for each gem? Will Ruby try to access the gem files as a non-root user (and if so, what user / group would Ruby use and how would I find out)?
What would be the symptoms of an application that is broken due to bundler being used as root?
My specific reason for asking is because I'm trying to use bundler on a very basic Centos VPS where I have no need to set up any non-root users. I'm having other problems with gems installed via bundler (Error: file to import not found or unreadable: gemname despite the gem in question being present in gem list), and I'm wondering if installing the gems via bundler as root might have made the files unreadable to Ruby.
I want to work out if I do need to set up a non-root user account purely for running bundler, and if I do, what groups and privileges this user will need to allow Ruby to run the gems bundler installs.
Or can I just chown or chgrp the gem folders? If so, does it depend on anything to do with how Ruby is installed? (I used RVM and my gems end up in /usr/local/rvm/gems/ which is owned by root in group rvm) This loosely related question's answer implies that unspecified aspects of how Ruby is installed influence bundler's permissions requirements.
Researching the "Don't run bundler as root" message only comes up with an unanswered question and complaints that this warning is apparently "like it saying to go to sleep at 8PM" (link contains NSFW language).
So I had to dig into the git log history of bundler's repo, because GitHub doesn't allow search in git commits messages anymore.
The commit c1b3fd165b2ec97fb254a76eaa3900bc4857a357 says :
Print warning when bundler is run by root. When a user runs bundle install with sudo bundler will print a warning, letting
them know of potential consequences.
closes #2936
Reading this issue, you understand the real reason you should not use the root user:
Running sudo bundle install can cause huge and cascading problems for
users trying to install gems on OS X into the system gems. We should
print a warning and explain that Bundler will prompt for sudo if it's
needed. We should also warn people that sudo bundle will break git
gems, because they have to be writable by the user that Bundler runs
as.
Pretty fundamental question but I'm trying to understand how best to use Bundler in a deployment situation.
I'm working on a Sinatra application that has about 20 dependent gems. During development, I'm using RVM with a custom gemset for the application, and I run bundle install to update the gemset in accordance with the gemfile.
When it comes to deployment (manually for now, so I can understand how it all works before using a tool like capistrano), I need to do bundle install --development right? This downloads the gems and places them in vendor/bundle.
My question is what else do I need to do? I'm using Unicorn on the server - do I just bundle exec unicorn ... and everything just works? (i.e. bundler finds the vendor directory and uses the gems from there?)
Should unicorn be a vendored gem in the application or a separate 'system' gem on the server that all applications share?
You need --deployment key, not --development: http://gembundler.com/man/bundle-install.1.html#DEPLOYMENT-MODE
On first run bundler creates config in .bundle directory. You can check it by running bundle config or just cat .bundle/config in project's directory. So bundle exec unicorn is enough since bundler knows where gems are installed. On development machine you can also install gems to arbitrary directory using --path key. For more details see manpage for bundle install (link above or bundle help install).
I accidentally ran sudo bundle install smtp_mail and now all my gems are in this directory called smtp_mail inside my Rails app.
I'm not sure about the default location of gems? And, my Rails app is complaining when it starts. Is there a way I can revert back?
After a bit of Googling around i was able to find the answer
Just run:
sudo bundle install --system and you'll have your gems back at their appropriate system directories.
The path is specified in a file located in
.bundle/config
If you delete the .bundle directory and then delete your smtp_mail directory you will be back at square one. If you really want a local (to your app) installation of the gems, I recommend you run
bundle install --path vendor/bundle
Good luck!
pay attention on this...
from the bundle man page:
By default, bundler installs gems to the same location as gem install.
You should never use sudo bundle install. This is because several other steps in bundle install must be performed as the current user:
Updating your Gemfile.lock
Updating your vendor/cache, if necessary
Checking out private git repositories using your user's SSH keys
Of these three, the first two could theoretically be performed by chowning the resulting files to $SUDO_USER. The third, however, can only be performed by actually invoking the git command as the current user. Therefore, git gems are downloaded and installed into ~/.bundle rather than $GEM_HOME or $BUNDLE_PATH.
As a result, you should run bundle install as the current user, and bundler will ask for your password if it is needed to put the gems into their final location.
This helped me when I ran into a simular issue.
I rm -rf all files in .bundle and then removed and then I followed the commands in this document.
http://ruby-korea.github.io/bundler-site/issues.html.
I have a machine that is running Ubuntu Hardy, which provides its own RubyGems package. Unfortunately that version of RubyGems (1.1.1) is too old to do anything useful with, so I decided to manually update RubyGems to the current version (1.3.6). That part went smoothly, and if I do gem -v, I get 1.3.6 which is expected. The problem is when I try to do: sudo gem install rack, it returns this error:
ERROR: While executing gem ... (Errno::EACCES)
Permission denied - /home/username/.gem
Usually when I install gems as root, it knows to install it into /usr/lib/ruby/gems, so why is it checking my home directory at all? Another quirk is when I do gem install rack (not as root), it says:
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions into the /usr/lib/ruby/gems/1.8 directory.
which is where I want it to go. I've already tried clearing source_caches, trying different versions of RubyGems (1.3.5), forcing installation into /usr/lib with -i to no avail. Any ideas on why RubyGems is so insistent on checking my /home directory when installing as root?
Sounds like it could be a path issue coupled with having multiple versions installed.
Any difference in output between:
sudo gem env
and
gem env
Try running:
gem environment
and checking the values for the GEM PATH. More info at http://docs.rubygems.org/read/chapter/10#page31
I was running into the same problem myself on Fedora 15, so I ran 'gem install' with the '--backtrace' option to see what was going on.
It turned out it was failing at /usr/lib/ruby/site_ruby/1.8/rubygems/doc_manager.rb:203 where it tried to chdir to the directory it had previously stored (the home directory of the user I was running sudo as)
I didn't extensively debug to see what the underlying cause was, just rather used a quick workaround so I could continue moving forward. The workaround was simply to cd to the root directory, eg cd /, before running the gem install command.
Hope this helps / solves your issue.
Woulda been easier to su (password) then chmod 755 /usr/lib/ruby/gems/1.8