12

I've got a Sinatra "hello world" app that I am trying to run using jRuby. It works when I run the app, but not when I run rackup. Can anyone tell me what is going on here?

Here's the app, in a file 'app.rb':

require 'rubygems'
require 'bundler/setup'
require 'sinatra'

configure do
  set :bind, '0.0.0.0'
end

get '/' do
  'Boo!'
end

I can run this using bundle exec ruby app.rb and it works fine:

jonea@centos7andy[~/andy/sinatra_sand_jruby]%: bundle exec ruby app.rb
[2015-01-12 10:36:06] INFO  WEBrick 1.3.1
[2015-01-12 10:36:06] INFO  ruby 1.9.3 (2014-12-09) [java]
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from WEBrick
[2015-01-12 10:36:06] INFO  WEBrick::HTTPServer#start: pid=31654 port=4567

Here is my config.ru to call the above program:

require 'rubygems'
require 'bundler/setup'
require 'sinatra'
require './app'

run Sinatra::Application

If I run this, it appears to work, but I can't access the server using a web browser:

jonea@centos7andy[~/andy/sinatra_sand_jruby]%: bundle exec rackup -p4567
[2015-01-12 10:29:06] INFO  WEBrick 1.3.1
[2015-01-12 10:29:06] INFO  ruby 1.9.3 (2014-12-09) [java]
[2015-01-12 10:29:06] INFO  WEBrick::HTTPServer#start: pid=31553 port=4567

I note the suspicious lack of "Sinatra has taken the stage..."

kares
  • 7,076
  • 1
  • 28
  • 38
Andy Jones
  • 1,074
  • 1
  • 10
  • 21

4 Answers4

37

When you run the Ruby file directly (or when you add Sinatra.run! to the config.ru file) Sinatra runs its own server. In this case the call to set :bind, '0.0.0.0' will take effect. When you run through rackup this setting is ignored.

The default host that rackup listens to is localhost, so the server will only be available through the same machine, you won’t be able to access it from other machines. To access it through other machines set the --host option:

bundle exec rackup -p4567 --host 0.0.0.0

(Note the output of rackup -h for the current version says the default host is 0.0.0.0, but this is out of date and has been fixed in master.)

matt
  • 78,533
  • 8
  • 163
  • 197
  • That's a nice theory -- but it doesn't explain a failure under jRuby explicitly. I should have explained that this works fine under MSI Ruby. – Andy Jones Jan 12 '15 at 16:56
  • @AndyJones what versions of rack are you using under MRI and JRuby? If you have an older version in MRI it would explain the difference. The change to only listen to localhost is only in rack 1.6+. – matt Jan 12 '15 at 17:01
  • Ruby 1.9.3, Rack 1.6.0 I'm afraid. I will retest under MSI tomorrow to make sure this still works, though, thanks. – Andy Jones Jan 12 '15 at 17:08
  • I have the `bind 0.0.0.0` in my `configure do` so I'm not using it. – Andy Jones Jan 14 '15 at 08:39
  • The `configure do` and the `:bind` option only affect the server that Sinatra uses itself when you run the file directly (or use `Sinatra.run!`). If you want to set the host when using `rackup` you need to use the `--host` option to it. It’s the rack version of the Sinatra `:bind` setting. – matt Jan 14 '15 at 15:57
  • Matt, that appears not to be the case; see my own answer to this question. I can change the config.ru and make it work without adding a `--host` parameter or fiddling with the `bind` option. The problem is that I don't know WHY this works, and my config.ru no longer looks anything like the Sinatra documentation... – Andy Jones Jan 15 '15 at 09:02
  • Matt: also, if that were true, it would presumably be true also for MSI ruby? Cos it isn't. – Andy Jones Jan 15 '15 at 09:05
  • `Sinatra::Application.run!` starts the _Sinatra_ built-in server. When you have this line in your `config.ru` you tell Sinatra to start its own server before the rack one. But you don’t actually specify an app for rack to start, so when you exit the server rack will try and continue but not find anything to run. Check your output when you do that – do you get an error like `missing run or map statement` after you stop it? – matt Jan 15 '15 at 15:49
  • You can also set the option in the `config.ru` if want to avoid needing it from the command line – add `#\ --host 0.0.0.0` at the top. (See https://github.com/rack/rack/wiki/%28tutorial%29-rackup-howto.) – matt Jan 15 '15 at 15:59
  • Matt, there is no error like that, and this doesn't happen in MSI Ruby, so -- how can I put this politely? -- your explanation of events turns out not to be true. – Andy Jones Jan 16 '15 at 08:32
  • So you’re saying that if you have a `config.ru` that _doesn’t_ have a `run Sinatra::Application` line (or a different `run x`x` or `map xxx`) line you don’t get an error when you run `rackup`? You definitely should get an error in this case, as you are not telling rack what app to run. – matt Jan 16 '15 at 11:17
  • Also, are you trying to connect from a browser running on the same machine or from a different one? My explanation is only for connecting from a different machine, which suggested itself because you are only setting the host when running the server via Sinatra. If you can’t connect from the same machine there may be some other problem as well. If so you’ll likely need to provide more information. – matt Jan 16 '15 at 11:22
  • MSI Ruby: `run Sinatra::Application` works. jRuby: doesn't, but `Sinatra::Application.run!` does. Yes, I'm running the Sinatra on a headless machine somewhere in our stacks, and testing it from my desktop. – Andy Jones Jan 16 '15 at 14:30
  • What about `bundle exec rackup -p4567 --host 0.0.0.0` on JRuby? – matt Jan 16 '15 at 14:36
  • what about it? Please re-read the question. I have a set of circumstances that work and a set that do not, and neither appear to involve the host/bind definition. The fact that I can get this to work without changing the host/bind definition pretty much demonstrates that this has nothing to do with it. – Andy Jones Jan 20 '15 at 08:47
  • Sorry, that was a bit sarcastic. Are you testing MRI and JRuby from exactly the same directory on the server, so that they are using the same `Gemfile` and `Gemfile.lock`? My suspicion is that you are somehow testing MRI and JRuby with different versions of Rack, so that the new default (listening to localhost) is only effecting JRuby, whilst MRI is using an older version of Rack that listens on 0.0.0.0. Also: you should be able to check where the app is listening with something like `netsat`. – matt Jan 20 '15 at 16:13
  • Note there are _two_ host settings, one for Sinatra, and one for Rack. When you use `ruby app.rb` or when you have `Sinatra::Application.run!` in your `config.ru` you are using the `set :bind, '0.0.0.0'` setting, which is the Sinatra one. When you use `run Sinatra::Application` in your `config.ru` you need to use the rack setting, which is `--host 0.0.0.0`. Note that having `Sinatra::Application.run!` in the `config.ru` isn’t using rack to start the server. – matt Jan 20 '15 at 16:13
4

Well, this is hardly sufficient to explain what is going on, but I can make it work if in config.ru I replace

run Sinatra::Application

with

Sinatra::Application.run!

In fact, knowing that makes me even more confused. Some sort of bug in Rack?

Andy Jones
  • 1,074
  • 1
  • 10
  • 21
2
#config.ru
require "./app.rb"

set :bind, '0.0.0.0'
set :port, 9292 #set your port!
Sinatra::Application.run!

try this code and type rackup

Then you can get the results you want.

Tongil kim
  • 53
  • 6
  • As explained by matt, this is *not* the right solution. If you use `Sinatra::Application.run!` you don't need `rackup` at all. – Franklin Yu Nov 14 '18 at 20:50
  • `set :bind, '0.0.0.0'` works and is necessary for both `ruby config.ru` and `rackup`. It also requires `Sinatra::Application.run!`. Thanks. – mmell Oct 17 '19 at 20:44
1

I have slightly similar situation. But the difference is that, my Jruby + Sinatra rackup app is finally starts responding.

But it takes lots of time, sometimes it starts responding 5 minutes after app start. I found out, that after app start port is not listened for some period time.

If we make netstat -an it will not show our app port. Actually I don't know the reason of such behavior, but I'll dig for it.

Stanislav Mekhonoshin
  • 4,276
  • 2
  • 20
  • 25
  • Having a similar problem, did you ever figure it out? – Kevin Bullaughey Jan 05 '16 at 21:51
  • After upgrade to jruby-9000 it has gone. No idea what was the root of problem – Stanislav Mekhonoshin Jan 05 '16 at 21:57
  • Thanks. In my case, this behavior only happened on DigitalOcean (not my mac, in or outside docker), and on the droplet in question I couldn't even get jruby-9000 to install (it just hung), so I built a new droplet on the latest ubuntu and installed docker myself, and it worked. It did not simply work to build a new droplet using the stock ubuntu+docker app. I have no idea whether this problem was a docker version problem, an Ubuntu version problem, or a DigitalOcean problem or some combination. – Kevin Bullaughey Jan 06 '16 at 03:09
  • 1
    Actually, it turned out to be blocking on insufficient entropy available to `/dev/random` which can be ["fixed" by using an insecure source](https://docs.oracle.com/cd/E13209_01/wlcp/wlss30/configwlss/jvmrand.html). This seems particularly relevant to DigitalOcean droplets for some reason. – Kevin Bullaughey Jan 06 '16 at 05:40