JRuby with Sinatra on Heroku - ruby

I'm cloning this repo:
https://github.com/freeformz/sinatra-jruby-heroku.git
to try and use JRuby/Sinatra on Heroku's Cedar stack. I follow the included instructions and everything runs great locally with a 'foreman start'. I then git push to Heroku and it initially loads up fine but when I try to access the site I get an error in the logs:
jruby: No such file or directory -- trinidad (LoadError)
So it seems jruby can't find the "/app/.gems/bin/trinidad" file. I initially thought it wasn't there because .gems/ is in the .gitignore file, but I'm pretty sure Heroku creates that server side on a git push.
$APPDIR/.gems is added to the PATH so Heroku should be able to see the trinidad script. I've also tried to change the Procfile around to play with the path like:
web: script/jruby -S bin/trinidad -p $PORT
But no dice. Has anyone had any success deploying anything JRuby to Heroku cedar?
Thanks

As of Bundler 1.2 you are now able to specify the Ruby implementation and version in your Gemfile. The nice thing about this is that Heroku will understand these settings and prepare the your Heroku application for your environment.
Take this Gemfile for example:
source "https://rubygems.org"
ruby "1.9.3"
gem "rails"
gem "puma"
What's cool about this is that by default Celadon Cedar uses Ruby 1.9.2. However, when you specify ruby "1.9.3" in the Gemfile it'll actually compile Ruby 1.9.3 for your Heroku environment.
Now, if you want to add a different Ruby implementation to your Heroku environment, you can do so like this:
source "https://rubygems.org"
ruby "1.9.3", :engine => "jruby", :engine_version => "1.7.0.preview1"
gem "rails"
gem "puma"
Now it'll install and use JRuby 1.7.0.preview1 in Ruby 1.9 mode for your Heroku application upon deployment. It'll also even define the proper JVM options in the Heroku environment variables.
Best of all is that this comes with the official Heroku buildpack, so there is no need to switch to a 3rd party buildpack to get the JRuby/JVM going on Heroku. Although I haven't gotten it to work yet, this should also work with Rubinius, but I believe it's currently bugged. Either that, or I'm doing it wrong.
This is in my opinion an awesome and scalable feature. Just define the Ruby implementation/version/mode you're using in your Gemfile along with your other dependencies and Heroku will ensure the environment is prepared.
Now, with all this in place, Heroku should create binstubs (through Bundler) in APP_ROOT/bin so what you can do is for example this:
web: bin/trinidad -p $PORT -e $RACK_ENV --threaded
Just don't use bundle exec since JRuby doesn't play nice with that. Always use the binstubs provided by Bundler which are always located in APP_ROOT/bin on Heroku.

I believe the details about including gems on this blog entry might be helpful to you:
http://chris.chowie.net/2011/08/28/Sinatra-with-JRuby-on-Heroku/

I suspect that your gems are not in /app/.gems but rather in /app/vendor/bundle
You can find out by running this command:
heroku run ls /app/.gem
heroku run ls /app/vendor/bundle
Either way, you should probably add the GEM_HOME/bin to the path, and not the GEM_HOME as you state.
I've got a blog post on running Jruby and Trinidad on Heroku here:
http://deployingjruby.blogspot.com/2012/03/deploying-with-trinidad-on-heroku.html
And an example app here:
https://github.com/jkutner/jruby-trinidad-heroku
Some of the other material you may find is a little out of date.

Related

Ruby: Unable to start worker - check_for_activated_spec

I am unable to run some of my jobs in sidekiq. And it seems to be somehow related to Bundler.. Maybe.
when I run my puma server with pumactl start in the logs I am getting:
[156149] ! Unable to start worker
[156149] /home/todd/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/bundler-2.3.25/lib/bundler/runtime.rb:309:in `check_for_activated_spec!'
Currently I'm on sidekiq 6.5.6 and Bundler 2.3.25
Anyone know of any issues with those two versions or anything else that may be causing this?
EDIT:
The interesting thing is when I start puma with bundle exec pumactl start I get a totally different error:
[ActionDispatch::HostAuthorization::DefaultResponseApp] Blocked host:
But my host is defined in my development.rb file.. in fact I've added the following, so NO hosts should be blocked:
config.hosts << /.*\.ngrok\.io/
config.hosts.clear
Then finally if I just start puma with a rails s all is fine, just my sidekiq worker won't run correctly.
Let's say that you want to start using Rails and one day you follow the general installation instructions which say that you should run this command:
gem install rails
And you get this output:
...
Successfully installed rails-7.0.1
You also start working with puma and sidekiq and install those gems for the convenience of running pumactl start and sidekiq:
gem install puma
...
Successfully installed puma-5.6.2
gem install sidekiq
...
Successfully installed sidekiq-6.4.2
Then after a day or a week or a month of tinkering you create a new Rails app:
rails new app
And since you want to use Sidekiq you add that to your Gemfile, which looks something like this:
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "puma", "~> 5.6.2"
gem "rails", "~> 7.0.1"
gem "sidekiq", "~> 6.0"
But you know that there are newer versions of those gems so you update your Gemfile to look like this:
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "puma", "~> 6.0.0"
gem "rails", "~> 7.0.4"
gem "sidekiq", "~> 7.0"
And then you run bundle install and the gems update. Or maybe you don't change the versions, but some day run bundle update which uses the ~> versioning operator and updates the gems to newer versions.
Here's where you're going to start running into compatibility problems.
First problem:
When you installed the sidekiq and puma and rails gems to run their scripts like pumactl they were installed using gem install ... which installed them globally and with a specific version.
When you added them to your Rails app and updated the versions they were installed separately by bundler with specific versions that are noted in Gemfile.lock.
Now your global version of puma is 5.6.2 and your bundled version of puma is 6.0.0.
Trying to manage puma using an old version of the CLI with a new version of the gem isn't guaranteed to work and can introduce hard-to-pinpoint problems. The same is true of the rails and sidekiq gems and any gem with a CLI.
Second problem:
When you run scripts like pumactl they aren't necessarily going to look at your application's Gemfile.lock and they aren't guaranteed to see or respect bundler's configuration for your Rails app when it loads it.
When you run scripts prefixed with bundle exec (like bundle exec sidekiq) it uses bundler to look at your bundled environment and ensure that all the dependencies are properly loaded.
Trying to run a bundled application without bundle exec can introduce hard-to-pinpoint problems. The same is true for any gems that have CLI tools.
Short answer
Always use bundle exec ... to run gem CLIs in your app, whether it's bundle exec rails server or bundle exec puma or bundle exec sidekiq. This will ensure that your app is started or managed using the bundled gem rather than the global version.
If you see errors when starting your app using bundle exec ... then pay attention to them because they are indicative of actual problems that need to be addressed. Likewise, if you do see errors with bundle exec but don't see errors when starting your app using globally installed gems then pay attention to them because it means your app is not portable -- it's likely that it is papering over bugs to make the app run and that your app will not run on another computer.
Extended answer
pumactl start gives you an error -- probably because you aren't using bundle exec.
bundle exec pumactl start gives you a different error -- possibly because you're bypassing the standard way to start Rails; pumactl will read configu.ru and config/puma.rb and decide how it wants to start Rails. Use bundle exec rails server instead.
rails s doesn't load your sidekiq worker -- because you aren't using bundle exec rails s it likely can't see the things it's supposed to see to start properly, because it isn't using your bundled app config
Because the errors that you're reporting are due to a misconfiguration of your system and app I can't give you any more detailed answers. You need to fix your configuration first and determine which of the three different errors you're experiencing is valid. It's a lot of work to try to work through all three questions. A standard "vote to close" reason for questions is:
Needs more focus
This question currently includes multiple questions in one. It should focus on one problem only.
I'm not voting to close your question but I'm mentioning it in case it does get closed later.
I recommend that after you fix the misconfiguration you create a new post about that specific error with a minimal reproducible example.

Ruby: CLI script failing when requiring gems installed through git

I am patching a script, and want to run code from a repo I manage that has patches.
The gem in question is not installed through a published gem but through a github link
When requiring any gem that is normally installed. The script works. But requiring any gem that is installed through a github link fails. Any suggestions?
If I understand the problem correctly, there are a few solutions:
Clone the gem that's only available via the github link, build the gem locally, install it. You should be able to require it
You might be able to manage the project with bundler and a Gemfile. Instructions here for the syntax. Bundler basically does what I suggested above, for you. I don't think gem can install a gem from a remote natively?
Would love to see some more clarification, and if you're using a Gemfile the relevant snippets
So the issue was I was running the script in question using ./bin/path/script
This will not work if the script includes github referenced gems, you need to prefix this with bundle exec which is not immediately obvious, given that when you use non-github referenced gems, it works fine without it.
Now running bundle exec ./bin/path/script will work for both, it's probably just better using that wherever possible.

Changing Ruby version during deploy

I have a box with 3 Rails apps on it. I wan't to upgrade one of the apps so that it uses Ruby 2.0.0, while leaving the others running on 1.9.3-p394. I have both those Rubies installed via Rvm.
I'm trying to control the Ruby version that each app uses via it's Gemfile.
# Gemfile
ruby '2.0.0'
So, I changed the version number in the Gemfile locally, made sure it all worked, committed and now I'm trying to deploy the change to the server.
However, the cap deploy fails at this point
bundle install --gemfile [path to release Gemfile] --path [path to app bundle] --deployment --quiet --without development test
because
Your Ruby version is 1.9.3, but your Gemfile specified 2.0.0
This is correct technically, my Gemfile does specify 2.0.0 and the app is currently running on 1.9.3. I'm trying to make it change versions before bundling though. How do I do that?
Your PATH is not set up correctly. You probably don't have bin: as the first entry in your path. That would lead to this error.
Even if you're not using Heroku it's worth reading this page on troubleshooting that issue: https://devcenter.heroku.com/articles/ruby-versions
Here is a link to an answer which will explain how to change your PATH on the server: Capistrano: Can I set an environment variable for the whole cap session?
If you have rvm maybe you can try to do
rvm use 2.0.0
before your bundler call.
If you're using rvm set the default to ruby 2.0.0 on your server
rvm --default use 2.0.0
Resolved the problem for me deploying to an AWS server from my mac - but I guess if I need to update my older sites I'll have to set the default back to 1.9.3 before deploying.

How to deploy a Test App on Dreamhost Rails 3.0.4?

All this weekend I have been trying to setup a Rails 3.0.4 app in production on a Dreamhost shared server. I have followed this wiki article to have my own set of rubygems setup on the server. Furthermore, I also installed rvm and ruby 1.9.2 using the following command:
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
rvm use 1.9.2 --default
Doing ruby -v returns ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux], so I believe rvm has installed the version of ruby correctly.
I created my app forcing the use of a mysql database, and then generated an articles controller:
rails new test_app -d mysql
cd test_app
rails g scaffold articles title:string body:text
Now when I visit the domain I see the usual "Welcome aboard You’re riding Ruby on Rails!" screen, but if I click the "About your application’s environment" link I get what looks like to be some kind of passenger error:
Ruby (Rack) application could not be started
The application has exited during startup (i.e. during the evaluation of config/environment.rb). The error message may have been written to the web server's log file. Please check the web server's log file (i.e. not the (Rails) application's log file) to find out why the application exited. If that doesn't help, then please use the backtrace below to debug the problem.
Lastly, if I SSH into the server and just do rails s I can see the app functioning correctly on port 3000.
I have never put an app into production before, so I am very confused. Is passenger not using the RVM version of ruby? Is these even possible on a DreamHost shared server? What do I have to do to rectify this problem?
Any help is appreciated, Thanks.
I've been able to successfully get a Rails 3.2.2 app deployed to Dreamhost. Here are some notes I've written for myself.
On the local development machine
First off, Dreamhost Passenger is based on Ruby 1.8.7, not Ruby 1.9.2. Because of this, Dreamhost won't like some of your Ruby code because it has some of the new key value syntax. So look for any code like this:
key: "value"
and change it to Ruby 1.8.7 style (which Ruby 1.9.2 also can understand):
:key => "value"
I found that you can find this code by doing something like this...this can be done more efficiently on a *nix box, but this is how I did it in Windows with some *nix commands installed:
egrep -r -i "^.*\w: .*$" . | grep rb
After fixing the syntax, you'll want to bundle up your gems so Dreamhost doesn't complain about your rack version.
$> bundle package
On the Server (aka Dreamhost)
(Get your files on dreamhost. Personally, I commit and push changes into a git remote repository, then git pull them down to a private folder on dreamhost. After they are there, I copy them into the Passenger folder)
Then I run these commands from the Rails application folder (/home/username/www.myapp.com/):
$> bundle install --path vendor/bundle --local
$> rake db:migrate RAILS_ENV="production"
$> bundle exec rake assets:precompile
$> touch tmp/restart.txt
Voila, this seems to work. If it still isn't working, check the log/production.log.
I've bumped into the same problem. I believe it's because passenger is not loading the ruby interpretor you specify in rvm as it or gems you specify. You'll likely see that the gems being loaded refer to /usr/...
I did bump into this http://blog.ninjahideout.com/posts/the-path-to-better-rvm-and-passenger-integration, but I haven't been able to get around that Dreamhost is using ruby 1.8.7 in it's passenger configuration and you and I would like to use 1.9.2

Installing a gem from Github with Bundler

I am trying to use the instructions here to install a pre-released version of a gem with bundler.
The "bundle install" output lists the gem as getting installed, but "gem list" fails to find it.
My Gemfile:
source :gemcutter
gem 'sinatra', '1.1.0', :git => 'http://github.com/sinatra/sinatra.git'
gem 'RedCloth', '4.2.3'
Here is a gist with the rest of my sample code.
Has anyone gotten this scenario to work?
NOTE: I am also using RVM (on OS X). bundle show does list the gem (and dependencies) as existing, but I am not able to properly resolve them.
Thanks.
I would look at the load paths, and further debug from there, example:
...(master) $ irb
irb(main):001:0> $LOAD_PATH.count
=> 8
irb(main):004:0> require 'bundler/setup'
=> true
irb(main):005:0> $LOAD_PATH.count
=> 112
irb(main):006:0>
Bundler configures the load path for you, this means not all the gems are included on your load path by default.
Additionally, from the bundler git help:
Because Rubygems lacks the ability to handle gems from git, any gems installed from a git repository will not show up in gem list. They will, however, be available after running Bundler.setup.
Best regards, hope this helps
ED
Bundler might have installed it locally to your app. This could vary wildly, depending on OS and whether you are using RVM.
What is the output of bundle show sinatra?
In my case, sinatra was installed here:
/home/marshall/.rvm/gems/ruby-1.8.7-p302#3846859/bundler/gems/sinatra-9cfa74a7f352
Sinatra doesn't show in the gems list, but the server launches correctly if I execute rackup.
Gems installed via bundler on Engine Yard go to a different folder to isolate them.
it's usually /data/APP_NAME/shared/bundled_gems
To be sure, check your .bundle/config file on your APP folder at Engine Yard
It looks like there is an issue using Shotgun and Bundler (git repositories only).
If I use rackup to start up my app, all is well. I am going to investigate a little more and then file a bug with one (or both) of the projects.

Resources