0

I have built a node.js app that listens for webhooks. Currently it is used to build a jekyll website.

I have configured it on my server and jekyll build works perfectly when I run it in the root of my jekyll website (which is sending the hooks). When I run the node.js app over ssh in a shell everything works fine as well when a git hook is triggered.

However, when the node.js app is run from an upstart script (shown below) it doesn't seem to find the gems. It keeps asking for dependencies which I am sure I have installed (globally as well as for my user).

Inside the script I have put echo`which jekyll` and this shows that it is indeed pointing to the locally installed jekyll bin: /home/christophe/.gem/ruby/2.0.0/bin/jekyll. But right below that I execute the jekyll command and it fails:

/usr/lib/ruby/2.0.0/rubygems/dependency.rb:296:in `to_specs': Could not find 'jekyll' (>= 0) among 31 total gem(s) (Gem::LoadError)
    from /usr/lib/ruby/2.0.0/rubygems/dependency.rb:307:in `to_spec'
    from /usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_gem.rb:47:in `gem'
    from /home/christophe/.gem/ruby/2.0.0/bin/jekyll:22:in `<main>'

How can I execute this bash script to properly execute jekyll?

Upstart

# /etc/init/libservice.conf
# Task to automatically start the library service.

author "Christophe De Troyer"
description "Run the githook for the blog."

# Path of the configuration files
env PROJ="/home/christophe/jekyll-builder"

# Configure to run as `christophe`
setuid christophe
setgid christophe

script
    export PATH=/home/christophe/.gem/ruby/2.0.0/bin:$PATH
    cd $PROJ
    gulp run
end script    

start on startup
#Respawn the process if it crashes
#If it respawns more than 10 times in 5 seconds stop
respawn limit 10 5

Build script

#!/bin/bash                                            

########################                               
# Parameters from Node #                               
########################                               

giturl=$1                                              
reponame=$2                                            
branch=$3                                              
ownermail=$4                                           
reporoot=$5                                            
htmlsink=$6                                            
www=$7                                                 

##########                                             
# Script #                                             
##########                                             

# Check to see if reponame exists. If not, git clone it
if [ ! -d $reporoot ]; then                            
    mkdir -p $reporoot                                 
    git clone $giturl $reporoot                        
fi                                                     

# Checkout and pull branch.                            
cd $reporoot                                           
git checkout $branch                                   
git pull origin $branch                                
cd -                                                   


echo `which jekyll` 
jekyll # fails                                   
# Run jekyll                                           
jekyll build -s $reporoot -d $htmlsink    # fails too

Update:

gem env while logged in as a user:

    RubyGems Environment:
  - RUBYGEMS VERSION: 2.0.14
  - RUBY VERSION: 2.0.0 (2014-01-12 patchlevel 384) [x86_64-linux-gnu]
  - INSTALLATION DIRECTORY: /var/lib/gems/2.0.0
  - RUBY EXECUTABLE: /usr/bin/ruby2.0
  - EXECUTABLE DIRECTORY: /usr/local/bin
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /var/lib/gems/2.0.0
     - /home/christophe/.gem/ruby/2.0.0
     - /usr/share/rubygems-integration/2.0.0
     - /usr/share/rubygems-integration/all
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/

gem env from within the script, executed from the node.js app running via upstart gives:

RubyGems Environment:
  - RUBYGEMS VERSION: 2.0.14
  - RUBY VERSION: 2.0.0 (2014-01-12 patchlevel 384) [x86_64-linux-gnu]
  - INSTALLATION DIRECTORY: /var/lib/gems/2.0.0
  - RUBY EXECUTABLE: /usr/bin/ruby2.0
  - EXECUTABLE DIRECTORY: /usr/local/bin
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /var/lib/gems/2.0.0
     - /.gem/ruby/2.0.0
     - /usr/share/rubygems-integration/2.0.0
     - /usr/share/rubygems-integration/all
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/

Notice that the GEM_PATHS is missing the home directory prefix in the second entry. I have tried resolving this by putting env GEM_PATH="/home/christophe/.gem/ruby/2.0.0" in the upstart script but that didnt change anything.

In the meanwhile I have solved it by intalling a list of deps manually as root. However, I don't think this is a good approach as the upstart is explicitly running as my user. And secondly, this software needs to run on a server I don't have root permissions on. So I would still like to know a fix.

sudo gem install jekyll
sudo gem install jekyll-gist
sudo gem install jekyll-cite
sudo gem install jekyll-scholar
sudo gem install addressable -v 2.3.5
sudo gem install yajl-ruby -v 1.2.0
sudo gem install pygments.rb
sudo gem install posix-spawn
  • The "GEM PATHS" bit is lacking the home directory path under upstart, so that would be one thing to look at--how does gem set that? – thrig Jan 8 '16 at 17:12
  • Yes, I have added that in the end. /.gem/ is not a valid path so I assume that it is meant to be my user gem path, but somehow it is missing the prefix. – Christophe De Troyer Jan 8 '16 at 17:13
  • 1
    Your build process is likely failing to source the same files that an interactive login does, it could be ~/.bashrc, ~/.bash_aliases, etc... ya may have the GEM_HOME environment variable and related PATH variable modifications stashed away within one of these files; see a related answer for the start of a bread crumb trail that goes into more detail... What happens if ya add something like export GEM_HOME="${HOME}/.gem" as well as export PATH="${GEM_HOME}/bin:${PATH}" near the top of your build script? – S0AndS0 May 16 at 1:33
0

Did you try setting the GEM_HOME environment? I was able to at least get an upstart service listing a custom install dir via something like:

cd
gem install rake --install-dir grepable

And then using a /etc/init/footest.conf service of:

author "Nobody"
description "Echo some details"

env GEM_HOME="/home/jdoe/grepable"

setuid jdoe
setgid jdoe

script
    /usr/bin/gem environment
end script    

start on startup
respawn limit 10 5

And after a reboot,

# fgrep -1 grep /var/log/upstart/footest.log
  - RUBY VERSION: 1.9.3 (2013-11-22 patchlevel 484) [x86_64-linux]
  - INSTALLATION DIRECTORY: /home/jdoe/grepable
  - RUBY EXECUTABLE: /usr/bin/ruby1.9.1
  - EXECUTABLE DIRECTORY: /home/jdoe/grepable/bin
  - RUBYGEMS PLATFORMS:
--
  - GEM PATHS:
     - /home/jdoe/grepable
     - /.gem/ruby/1.9.1

For a production service one presumably would use an --install-dir/GEM_HOME of somewhere suitable not in the vendor space nor your home directory.

0

After a few hours of agony I have finally fixed it.

The trick was to set the PATH to: /home/cdetroye/.rbenv/shims:/home/cdetroye/.rbenv/bin:/usr/local/bin:/usr/bin:/bin.

# /etc/init/libservice.conf
# Task to automatically start the library service.

author "Christophe De Troyer"
description "Run the githook for the blog."

# Path of the configuration files

env PATH=/home/cdetroye/.rbenv/shims:/home/cdetroye/.rbenv/bin:/usr/local/bin:/usr/bin:/bin

# Configure to run as `christophe`
setuid cdetroye
setgid cdetroye

script
    cd $PROJ
    gulp run
end script    

start on startup
#Respawn the process if it crashes
#If it respawns more than 10 times in 5 seconds stop
respawn limit 10 5

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.