Do installing gems on the Rails/PostGres droplet require sudo privileges?

October 21, 2016 124 views
Ruby Ruby on Rails Ubuntu

Hi, I created a droplet using the Rails/PostGres image for Ubuntu. After uploading my Rails app, I get these warnings when tryihng to run rake tasks ...

$ rake db:migrate
Ignoring binding_of_caller-0.7.2 because its extensions are not built.  Try: gem pristine binding_of_caller --version 0.7.2
Ignoring byebug-8.2.2 because its extensions are not built.  Try: gem pristine byebug --version 8.2.2
Ignoring debug_inspector-0.0.2 because its extensions are not built.  Try: gem pristine debug_inspector --version 0.0.2
Ignoring executable-hooks-1.3.2 because its extensions are not built.  Try: gem pristine executable-hooks --version 1.3.2
Ignoring gem-wrappers-1.2.7 because its extensions are not built.  Try: gem pristine gem-wrappers --version 1.2.7
Ignoring kgio-2.10.0 because its extensions are not built.  Try: gem pristine kgio --version 2.10.0
Ignoring nokogiri-1.6.7.2 because its extensions are not built.  Try: gem pristine nokogiri --version 1.6.7.2
Ignoring pg-0.18.4 because its extensions are not built.  Try: gem pristine pg --version 0.18.4
Ignoring raindrops-0.16.0 because its extensions are not built.  Try: gem pristine raindrops --version 0.16.0
Ignoring unicorn-5.0.1 because its extensions are not built.  Try: gem pristine unicorn --version 5.0.1
/home/abrownstein/.rbenv/versions/2.3.0/bin/rake: exception reentered (fatal)

So based on the warnings, I ran what they suggested to try ...

$ gem pristine binding_of_caller --version 0.7.2
Ignoring binding_of_caller-0.7.2 because its extensions are not built.  Try: gem pristine binding_of_caller --version 0.7.2
Ignoring byebug-8.2.2 because its extensions are not built.  Try: gem pristine byebug --version 8.2.2
Ignoring debug_inspector-0.0.2 because its extensions are not built.  Try: gem pristine debug_inspector --version 0.0.2
Ignoring executable-hooks-1.3.2 because its extensions are not built.  Try: gem pristine executable-hooks --version 1.3.2
Ignoring gem-wrappers-1.2.7 because its extensions are not built.  Try: gem pristine gem-wrappers --version 1.2.7
Ignoring kgio-2.10.0 because its extensions are not built.  Try: gem pristine kgio --version 2.10.0
Ignoring nokogiri-1.6.7.2 because its extensions are not built.  Try: gem pristine nokogiri --version 1.6.7.2
Ignoring pg-0.18.4 because its extensions are not built.  Try: gem pristine pg --version 0.18.4
Ignoring raindrops-0.16.0 because its extensions are not built.  Try: gem pristine raindrops --version 0.16.0
Ignoring unicorn-5.0.1 because its extensions are not built.  Try: gem pristine unicorn --version 5.0.1
Error loading RubyGems plugin "/usr/local/rvm/gems/ruby-2.2.1@global/gems/executable-hooks-1.3.2/lib/rubygems_plugin.rb": cannot load such file -- executable-hooks/wrapper     (LoadError)
Error loading RubyGems plugin "/usr/local/rvm/gems/ruby-2.2.1@global/gems/gem-wrappers-1.2.7/lib/rubygems_plugin.rb": cannot load such file -- gem-wrappers (LoadError)
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /usr/local/rvm/gems/ruby-2.2.1 directory.

But you see taht error about permissions. Am I required to use sudo when running gem installs/upgrades on the Rails/Postgres Ubuntu droplet?

1 Answer

tl;dr: Yes.
It's because you don't have permissions to write in /usr/local/rvm.
sudo will not work for it. This is because gem is only available to logged in user.
When you run gem pristine binding_of_caller --version 0.7.2 as non-root user it will give you this:

Output of gem pristine binding_of_caller --version 0.7.2
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /usr/local/rvm/gems/ruby-2.2.1 directory.

But why you execute sudo gem pristine binding_of_caller --version 0.7.2:

Output of sudo gem pristine binding_of_caller --version 0.7.2
sudo: gem: command not found

sudo and gem are not working together. If you have root password you can just change to it:

  • su - root

You can also SSH directly to root ssh root@droplet-ip if you didn't set PermitRootLogin to no.
Enter password and execute command.

  • Restoring gems to pristine condition...
  • Building native extensions. This could take a while...
  • Restored binding_of_caller-0.7.2

It's another story now.

You can also change the ownership of /usr/local while you do it:

  • sudo chown -R sammy:root /usr/local

Execute gem pristine and puff. It is working.
When you finish you can return to local to root if you want

  • sudo chown -R root:root /usr/local

Basically you need root privileges because of owner of /usr/local is root.
When you

  • ls /usr -l
ls /usr -l
total 48
drwxr-xr-x   2 root root 20480 Mar  3  2016 bin
drwxr-xr-x   2 root root  4096 Apr 10  2014 games
drwxr-xr-x  35 root root  4096 Mar  3  2016 include
drwxr-xr-x  60 root root  4096 Mar  3  2016 lib
drwxr-xr-x  11 root root  4096 Mar  3  2016 local
drwxr-xr-x   2 root root  4096 Mar  3  2016 sbin
drwxr-xr-x 121 root root  4096 Mar  3  2016 share
drwxr-xr-x   6 root root  4096 Feb 23  2016 src

So only root can write to /usr/local.
This is why you get permissions error, if you execute command as root user or change ownership, it is working :)

Have another answer? Share your knowledge.