Ruby a good choice for CGI?

Ive been messing around with Ruby for a few weeks now, and I’m fairly
comfortable with the language itself, but now I want to host a very
tiny app on the net, and I’m getting very overwhelmed with the massive
array of frameworks and technologies available.

I’ll describe what I’m trying to, and maybe someone here can just point
me in the right direction and spare me weeks of wading through doc to
find out all about each of these things.

I’ve written a small HTML/JQuery page that displays a simple UI on a
canvas element. The user clicks on pictures of buttons and the JQuery
posts a string to the server. I need some server side code - hopefully
ruby b/c i like the syntax, and i’ve heard bad things about PHP - that
will take the command from the POST, hit a MySQL db, and return a string
response. The JQuery takes the string response and updates the canvas.

Really simple right? I already have the HTML/JQuery/Canvas-draw. I’ve
already got the Ruby code itself, including the MySQL part.

I went to host it, and figured I’d try it at home before I spent any
money. I installed Apache on my Ubuntu box, dropped the Ruby files into
the cgi-bin folder, used the ruby cgi lib in my script and it all
worked. Then the plane crashed in the mountain.

I started reading online and people said pure CGI was way too slow b/c
I’ll be loading and disposing of all my code and db connections each
request. That sounds bad. So what do I do? I’ve be told things about
FastCGI, Passenger, mod_ruby, Rack, Sinatra, Camping, etc. and I can’t
even figure out which one I need!

Can someone point me in the right direction here? My app is VERY small.
Practically no code, no HTML output. All I need is to execute the 2 or 3
Ruby functions I already have, on the net, with some basic
cookie/session support. What’s the least headache(and not terribly slow)
way to do this?

find out all about each of these things.
already got the Ruby code itself, including the MySQL part.
even figure out which one I need!

Can someone point me in the right direction here? My app is VERY small.
Practically no code, no HTML output. All I need is to execute the 2 or
3
Ruby functions I already have, on the net, with some basic
cookie/session support. What’s the least headache(and not terribly
slow)
way to do this?

DISCLAIMER: I don’t actually use Ruby for webapps

CGI is ok, if and only if your web traffic is very low. If you
Expect a lot of traffic, or your traffic will be coming in bursts, you
definitely want to figure something else out. For something as simple
as you seem to be describing, I would recommend either mod_ruby, or
fastcgi. Mod_ruby is akin to mod_php5 or mod_python where the Ruby
interpreter is actually imbedded in the Apache server. FastCGI on
the other hand is similar to CGI, except that the process is reused
for requests rather than starting a new one for each request.

I’m not sure which will be easier, but either should be able
to handle what you need, and I think both should be fairly simple
setups.

Both are available in Ubuntu via:
sudo apt-get install libapache2-mod-fastcgi
sudo apt-get install libapache2-mod-ruby

I hope this helps!

On Wednesday 25 November 2009 01:12:19 pm Nick Dr wrote:

I’ve written a small HTML/JQuery page that displays a simple UI on a
canvas element. The user clicks on pictures of buttons and the JQuery
posts a string to the server. I need some server side code - hopefully
ruby b/c i like the syntax, and i’ve heard bad things about PHP - that
will take the command from the POST, hit a MySQL db, and return a string
response. The JQuery takes the string response and updates the canvas.

That sounds tailor-made for Sinatra. However, you should learn something
about
REST, first – are you sure POST is appropriate?

I’ve
already got the Ruby code itself, including the MySQL part.

Why MySQL specifically? Why not go with something database-agnostic,
like
Datamapper, Sequel, or ActiveRecord?

But hey, if you’ve already got it, it works.

I’ve be told things about
FastCGI, Passenger, mod_ruby, Rack, Sinatra, Camping, etc. and I can’t
even figure out which one I need!

FastCGI is obsolete, so scratch that.

Passenger and mod_ruby are essentially the same thing, IIRC. But my
understanding is that Passenger works with Rack, which doesn’t feel at
all
like CGI. So these might be deployment options, but they have nothing to
do
with how you write and develop your app.

So among your options are Sinatra and Camping. Camping is by _why, who
seems
to have disappeared, but I’m sure someone’s maintaining it… What I
like
about Sinatra is the sheer simplicity of:

get ‘/’ do
‘Hello, world!’
end

In your case, assuming you still want a POST, it’ll probably be
something
like:

post ‘/wherever’ do

build your string from the database and return it

end

Once you’ve got it working on localhost, if you can find a managed host
that’ll just let you upload a Rack app (especially if they know about
Sinatra), do that. Or you could do it yourself – right now, I’m liking
nginx
and Unicorn, which is what Github uses:

On the other hand, you could technically deploy this with Passenger.
Some
people find it easier, but I like deploying with Capistrano anyway.

some basic
cookie/session support.

http://www.sinatrarb.com/faq.html#sessions

What’s the least headache(and not terribly slow)
way to do this?

My vote is Sinatra.

On Wed, Nov 25, 2009 at 8:12 PM, Nick Dr [email protected] wrote:

way to do this?
I’ve been doing little apps with Sinatra and I’m very happy with it.
Pretty simple if you just need to implement 2 or 3 get requests:

require ‘sinatra/base’
class MyClass < Sinatra::Base
get ‘/’ do
“hello world”
end
end
MyClass.run!

Any rack-based framework (as Sinatra) can be deployed in a number of
ways including Phussion Passenger (apache) or most ruby webservers,
like Thin.

Hope this helps,

Jesus.

David M. wrote:
[…]

I’ve be told things about
FastCGI, Passenger, mod_ruby, Rack, Sinatra, Camping, etc. and I can’t
even figure out which one I need!

FastCGI is obsolete, so scratch that.

Passenger and mod_ruby are essentially the same thing, IIRC.

You do not RC. :slight_smile: Passenger is the same as mod_rails. mod_ruby is an
older module, suitable for CGI scripts but not Rails (and therefore I
would assume it’s not suitable for Sinatra).

But my
understanding is that Passenger works with Rack, which doesn’t feel at
all
like CGI. So these might be deployment options, but they have nothing to
do
with how you write and develop your app.

So among your options are Sinatra and Camping. Camping is by _why, who
seems
to have disappeared, but I’m sure someone’s maintaining it…

There’s also Merb, which is used by SproutCore sort of in the way the OP
is describing.

What I
like
about Sinatra is the sheer simplicity of:

get ‘/’ do
‘Hello, world!’
end

That looks nice! I plan to try Sinatra if I run into a project for
which Rails is excessive.

In your case, assuming you still want a POST, it’ll probably be
something
like:

post ‘/wherever’ do

build your string from the database and return it

end

Once you’ve got it working on localhost, if you can find a managed host
that’ll just let you upload a Rack app (especially if they know about
Sinatra), do that. Or you could do it yourself – right now, I’m liking
nginx
and Unicorn, which is what Github uses:

Unicorn! | The GitHub Blog

On the other hand, you could technically deploy this with Passenger.
Some
people find it easier, but I like deploying with Capistrano anyway.

They’re not mutually exclusive. Cap + Passenger is a great combination.

some basic
cookie/session support.

Sinatra: Frequently Asked Questions

What’s the least headache(and not terribly slow)
way to do this?

My vote is Sinatra.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Wednesday 25 November 2009 02:38:32 pm Marnen Laibow-Koser wrote:

David M. wrote:

Passenger and mod_ruby are essentially the same thing, IIRC.

You do not RC. :slight_smile: Passenger is the same as mod_rails. mod_ruby is an
older module, suitable for CGI scripts but not Rails (and therefore I
would assume it’s not suitable for Sinatra).

Ah. And probably not.

I guess it would make more sense, if it was called mod_ruby – it’s a
lot
closer to mod_perl than the current mod_ruby is, and it’s not
Rails-specific
anymore.

There’s also Merb, which is used by SproutCore sort of in the way the OP
is describing.

I’ve been trying to use Merb as a replacement for Rails in general. But
then,
I haven’t done much with either lately.

Unless something’s changed, there was a plan for Merb and Rails to merge

that Rails 3 would be Merb 2, and vice versa.

…and there’s also Ramaze. And Nitro. And…

It seemed like the original poster was asking someone to recommend a
single
choice. I think for that problem, Sinatra beats Merb, hands-down –
right down
to the fact that it’s constructing a text response.

On the other hand, you could technically deploy this with Passenger.
Some
people find it easier, but I like deploying with Capistrano anyway.

They’re not mutually exclusive. Cap + Passenger is a great combination.

Granted, but when I talk to people using Passenger, the #1 reason they
tell me
is ease of deployment – the idea that you’d just FTP up a file into a
certain
directory to restart your app.

Compared to that, ‘cap deploy’ seems at least as simple and MUCH safer.

And once you’ve got that set up, a more complex deployment only means a
more
complex cap script – the Github setup doesn’t really look harder to use
than
Passenger.

On Wed, Nov 25, 2009 at 12:52 PM, David M. [email protected]
wrote:

certain
directory to restart your app.

To my mind, Passenger’s appeal is that it embeds Rack in Apache - so you
get the benefits of mod_ruby (not restarting the interpreter with each
request) plus the benefits of Rack (although one does see critiques of
the
Rack/WSGI approach to middleware…) in one place. That’s a win in and
of
itself - but I’m a systems guy, and deployment was going to be something
(rake or cap)-ish anyway.

From: “Nick Dr” [email protected]

Can someone point me in the right direction here? My app is VERY small.
Practically no code, no HTML output. All I need is to execute the 2 or 3
Ruby functions I already have, on the net, with some basic
cookie/session support. What’s the least headache(and not terribly slow)
way to do this?

Others have already mentioned Sinatra, which looks nice. Another
framework which also allows starting very simple is Ramaze:
[ http://ramaze.net/ ]

require ‘ramaze’

class MainController < Ramaze::Controller
def index
“Hello, World! Server clock reads: #{Time.now}”
end
end

Ramaze.start :port => 9001, :adapter => :webrick

At this point the HTTP server is running on a custom port. However,
it’s not difficult to integrate that with the webserver, as described
here: http://wiki.ramaze.net/Deployment

Regards,

Bill

On 2009-11-25, Nick Dr [email protected] wrote:

Can someone point me in the right direction here? My app is VERY small.
Practically no code, no HTML output. All I need is to execute the 2 or 3
Ruby functions I already have, on the net, with some basic
cookie/session support. What’s the least headache(and not terribly slow)
way to do this?

How many hundred thousand hits a day do you have to process?

If the answer is “less than one”, you probably don’t care much about
speed in practice.

Past that… If you want something more interesting, I am pretty happy
with rails/passenger. Relatively low setup effort and works great, and
while it might be overkill for what you want to do, I really do find
it pretty rewarding.

-s

On Wednesday 25 November 2009 03:00:49 pm Judson L. wrote:

On Wed, Nov 25, 2009 at 12:52 PM, David M. [email protected] wrote:

Granted, but when I talk to people using Passenger, the #1 reason they
tell me
is ease of deployment – the idea that you’d just FTP up a file into a
certain
directory to restart your app.

To my mind, Passenger’s appeal is that it embeds Rack in Apache - so you

get the benefits of mod_ruby (not restarting the interpreter with each
request)

I’m confused. Wasn’t mod_ruby the one which restarts the interpreter
with each
request? I also don’t know of any Rack handler that restarts the
interpreter
with each request.

The supposed technical advantages of Passenger are that you’re building
on
Apache, that it’s actually somewhat production-ready but doesn’t require
complex reverse proxies, and it has something to do with Ruby Enterprise
Edition.

I’m curious, actually… I get why people might choose thin (really
quick
responses, so no real multitasking required – keep it simple), mongrel
(old-
ish and proven), unicorn (simple, reliable, prefork is proven), ebb (C
for
speed, and threads may be more efficient than forking), etc etc.

I don’t really see the case for Passenger over these, other than
simplicity of
deployment. Am I missing anything?

David M. wrote:
[…]

The supposed technical advantages of Passenger are that you’re building
on
Apache,

Sort of, although I think you can use it with Nginx and Thin.

that it’s actually somewhat production-ready

Strike the “somewhat”.

but doesn’t require
complex reverse proxies,

Right. It also doesn’t require clustered Mongrels. It’s about as easy
to set up as mod_php.

and it has something to do with Ruby Enterprise
Edition.

It’s written by the same people, and I believe it can take advantage of
some Ruby EE optimizations. But you can use it just as well with MRI
(although I’m not sure why you would – EE is much faster).

I’m curious, actually… I get why people might choose thin (really
quick
responses, so no real multitasking required – keep it simple), mongrel
(old-
ish and proven), unicorn (simple, reliable, prefork is proven), ebb (C
for
speed, and threads may be more efficient than forking), etc etc.

I don’t really see the case for Passenger

Incredible ease of configuration, EE optimizations. AFAIK, Passenger
has no serious competition on either of these points.

over these, other than
simplicity of
deployment.

Not app deployment so much as configuration. It really is about as easy
to set up as mod_php. I don’t know of any other Rails/Rack server setup
for which that can be said.

Am I missing anything?

You’re missing just about everything. :slight_smile: Personally, I’m not sure what
the case against Passenger is, unless you’re using Windows or JRuby.

Didn’t 37signals switch to Passenger some time ago?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Wed, Nov 25, 2009 at 2:17 PM, Brian C. [email protected]
wrote:

Well for one thing, many sites are a mixture of static assets and
dynamic content. It’s much more efficient to serve the static assets
from a webserver tuned for serving this sort of content, rather than
serving your entire site from a ruby server.

I wanted to amplify with use cases that run more than one app on the
same
server. My experience is that getting two Rails apps to play nicely
in
the same environment is a pain. But certainly easier than getting
Mongrel
to run PHP. With Passenger I can run Rails alongside PHP, and serve
static
content far more efficiently. (nginx is on my saw-sharpening list…)

Judson

Judson L. wrote:

On Wed, Nov 25, 2009 at 2:17 PM, Brian C. [email protected]
wrote:

Well for one thing, many sites are a mixture of static assets and
dynamic content. It’s much more efficient to serve the static assets
from a webserver tuned for serving this sort of content, rather than
serving your entire site from a ruby server.

I wanted to amplify with use cases that run more than one app on the
same
server. My experience is that getting two Rails apps to play nicely
in
the same environment is a pain. But certainly easier than getting
Mongrel
to run PHP. With Passenger I can run Rails alongside PHP, and serve
static
content far more efficiently.

And running multiple Rails apps with one Passenger installation is
likwise a breeze.

(nginx is on my saw-sharpening list…)

Judson

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

David M. wrote:

I’m confused. Wasn’t mod_ruby the one which restarts the interpreter
with each
request?

That would be CGI. Each incoming request forks off a new CGI handler,
which processes one request then terminates.

With the old mod_ruby, each Apache HTTP worker has an interpreter. If
Apache decides to fire up 20 workers because it’s handling 20 concurrent
connections, that’s 20 ruby interpreters. That may be wasteful if there
are mixed ruby and regular HTTP requests.

Phusion Passenger keeps a pool of Ruby processes, independent of the
httpd workers/threads, and picks a free worker to dispatch each ruby
request into. This makes it similar in some ways to fastcgi, but it’s
much easier to set up.

I also don’t know of any Rack handler that restarts the
interpreter
with each request.

You can run rack as a CGI, I belive. You would not be advised to.

something to do with Ruby Enterprise
Edition.

That’s the fork-friendly garbage collection. Passenger also prepares a
preloaded ruby interpreter with your app and forks it when it needs to
increase the size of the pool, rather than starting with a fresh ruby
instance which would have to read all the libraries in. Advantages: much
faster startup, and much more RAM sharing between ruby processes, so
less total RAM used.

I’m curious, actually… I get why people might choose thin (really
quick
responses, so no real multitasking required – keep it simple), mongrel
(old-
ish and proven), unicorn (simple, reliable, prefork is proven), ebb (C
for
speed, and threads may be more efficient than forking), etc etc.

I don’t really see the case for Passenger over these, other than
simplicity of
deployment. Am I missing anything?

Well for one thing, many sites are a mixture of static assets and
dynamic content. It’s much more efficient to serve the static assets
from a webserver tuned for serving this sort of content, rather than
serving your entire site from a ruby server.

For another thing, Rails is often still best run non-threaded. This
means you need multiple worker processes. With mongrel/thin/etc this
means running multiple servers bound to different ports, and that in
turn means sticking a proxy of some sort in front, and having the bits
and pieces necessary to start and monitor the required number of
workers, and sorting out things like proxying the SSL variables.

I bought Ezra’s Deploying Rails Apps book and built a system by
combining Apache, pen, mongrels, monit and capistrano. It works, but is
complex and a pain to add new apps. With Apache+Passenger it just works
out of the box, is easy to tweak, is far simpler, and you get the REE
memory sharing advantages too.

I don’t really see the case for deploying Rack or Rails apps using any
other approach, other than familiarity. Am I missing anything? :slight_smile:

Marnen Laibow-Koser wrote:

And running multiple Rails apps with one Passenger installation is
likwise a breeze.

  • although there’s some possibility for interaction between them. In
    particular, PassengerUseGlobalQueue gives one global queue across all
    apps, rather than one queue per application. Also,
    PassengerMaxInstancesPerApp can only be set globally rather than per
    app.

At least it was like that last time I enquired, but the current
documentation suggests this is still the case.

=

That sounds tailor-made for Sinatra. However, you should learn something
about
REST, first – are you sure POST is appropriate?

Ok I tried sinatra. It seems like it fires up webrick on port 4567, so I
take it there’s some config file I need to mess with, or my hosting
provider deals with so it’ll run on Apache instead?

Also, I can hit my sinatra ruby script from my browser, but when I tried
to hit it from a jQuery AJAX request, I get nothing back and the sinatra
console says that it was an OPTIONS request instead of the GET request
it reports when firefox asks for the page. What am I doing wrong here?
The idea was to jquery post to a ruby script for some JSON data and then
update my canvas based on that data.

FastCGI is obsolete, so scratch that.

The host I was considering, HostingRails, says they’ll do a FastCGI
deployment for me. I am (hopefully) expecting pretty high frequency
traffic. Like several hits/min 24/7, but never > 1000 hits per minute,
because this will be a global app available via facebook, so the time
zones should spread it out for me.
Are you sure FastCGI isn’t a good option for this?

Passenger and mod_ruby are essentially the same thing, IIRC. But my
understanding is that Passenger works with Rack, which doesn’t feel at
all
like CGI. So these might be deployment options, but they have nothing to
do
with how you write and develop your app.

So I can just use the Sinatra lib to route the request, deal with
cookies and sessions, and then hand it to my hosting provider and
they’ll set it up properly?

Thanks for all the advice!

Brian C. wrote:

Marnen Laibow-Koser wrote:

And running multiple Rails apps with one Passenger installation is
likwise a breeze.

  • although there’s some possibility for interaction between them. In
    particular, PassengerUseGlobalQueue gives one global queue across all
    apps, rather than one queue per application. Also,
    PassengerMaxInstancesPerApp can only be set globally rather than per
    app.

At least it was like that last time I enquired, but the current
documentation suggests this is still the case.

I think it may not be, but don’t quote me. :slight_smile:

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Thu, Nov 26, 2009 at 5:03 PM, Nick Dr [email protected] wrote:

=

That sounds tailor-made for Sinatra. However, you should learn something
about
REST, first – are you sure POST is appropriate?

Ok I tried sinatra. It seems like it fires up webrick on port 4567, so I
take it there’s some config file I need to mess with, or my hosting
provider deals with so it’ll run on Apache instead?

You can use Sinatra with JRuby to host the app via Google AppEngine,
that seems quite elegant. I don’t know how AppEngine’s pricing
compares to your other hosting offer of course.

http://blog.bigcurl.de/2009/04/running-sinatra-apps-on-google.html


Paul S.
http://www.nomadicfun.co.uk

[email protected]

Seebs wrote:

On 2009-11-25, Nick Dr [email protected] wrote:

Can someone point me in the right direction here? My app is VERY small.
Practically no code, no HTML output. All I need is to execute the 2 or 3
Ruby functions I already have, on the net, with some basic
cookie/session support. What’s the least headache(and not terribly slow)
way to do this?

How many hundred thousand hits a day do you have to process?

If the answer is “less than one”, you probably don’t care much about
speed in practice.

Past that… If you want something more interesting, I am pretty happy
with rails/passenger. Relatively low setup effort and works great, and
while it might be overkill for what you want to do, I really do find
it pretty rewarding.

Well, HOPEFULLY I’m expecting a lot of hits, but these scripts will also
be available via a facebook app, so hopefully the time zones will spread
it out for me, and I’ll be getting several hit per minute, 24/7, but
never a lot at once.

That brings up another question I had. Does
FastCGI/Mongrel/Thin/Passenger deal with multithreading for me? Like if
two people request an HTML page I figure it can just serve two copies of
it. But what about scripts? In theory my scripts only take milliseconds
from request to response, but just for arguments sake, if one person
requested it, it started running, hitting the db etc, and then another
person requested it before it was finished, what happens?

Ok I tried sinatra. It seems like it fires up webrick on port 4567, so I
take it there’s some config file I need to mess with, or my hosting
provider deals with so it’ll run on Apache instead?

If you have a Rails hosting provider, they can probably host Sinatra
too. Both just run on top of Rack.

If your hosting provider uses Phusion Passenger (= mod_rails), that can
host Sinatra.
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_sinatra

If you have a totally generic hosting provider then you may be stuck
running your app as a cgi-bin or fastcgi (although obviously they’ll
still have to provide you with a ruby interpreter). That may be enough
to get you started, but you’d probably be best changing to a different
hosting provider longer term.

I’ve run small fastcgi apps successfully; experience from many Rails
users has been that it has a tendency to explode. As a result, most ruby
people (and developers) are staying away from fastcgi. But it still
should be possible to build rack to work under fastcgi; see the README
in the rack gem. You’ll need the ruby fcgi gem, which in turn depends on
the C fcgi library.

Also, I can hit my sinatra ruby script from my browser, but when I tried
to hit it from a jQuery AJAX request, I get nothing back and the sinatra
console says that it was an OPTIONS request instead of the GET request

No idea on that. It all works for me. Use tcpdump to prove or disprove
that jQuery is sending an OPTIONS request; that would show if it’s a
problem with your jQuery code.

So I can just use the Sinatra lib to route the request, deal with
cookies and sessions, and then hand it to my hosting provider and
they’ll set it up properly?

Depends on how clued up and helpful your hosting provider is :slight_smile:

if one person
requested it, it started running, hitting the db etc, and then another
person requested it before it was finished, what happens?

Sinatra has a request lock turned on by default, so that the second
request will wait until the first completes, but you can turn it off if
you are sure your application is thread-safe.

However, running under fastcgi or mod_rails, only one request would be
sent at a time to your application. Therefore you will need to spawn
multiple processes to handle concurrent requests. This should be done
for you, but you may wish to tune the parameters for min/max processes
spawned.